[gimp] Bug 787457 - Paint brush settings display system language (e.g. zh_TW)



commit d01e182c7be27cbf44583c027f74615d09ac8f18
Author: Jehan <jehan girinstud io>
Date:   Mon Oct 9 00:21:29 2017 +0200

    Bug 787457 - Paint brush settings display system language (e.g. zh_TW)
    
    ... and ignore language setting (e.g. en_US).
    The problem came from the fact that these settings names are class
    properties of GimpPaintOptions/GimpContext which is first instanciated
    when the Gimp object is created. This unfortunately happened before
    language_init() since we needed these objects when loading gimprc
    (making inversion of calls rather complicated).
    Therefore they were localized with the system language, not the
    configured language.
    The solution was to create a very simple object GimpLangRC which
    implements the GimpConfig interface, for sole purpose to read the
    language from `gimprc` in a first pass. gimp_load_config() will still
    happen later as a second pass to properly load the rest of the
    configuration.

 app/app.c                 |   26 ++++-
 app/config/Makefile.am    |    2 +
 app/config/config-types.h |    1 +
 app/config/gimplangrc.c   |  285 +++++++++++++++++++++++++++++++++++++++++++++
 app/config/gimplangrc.h   |   60 ++++++++++
 5 files changed, 371 insertions(+), 3 deletions(-)
---
diff --git a/app/app.c b/app/app.c
index 775e379..377c18e 100644
--- a/app/app.c
+++ b/app/app.c
@@ -45,6 +45,7 @@
 
 #include "core/core-types.h"
 
+#include "config/gimplangrc.h"
 #include "config/gimprc.h"
 
 #include "gegl/gimp-gegl.h"
@@ -181,6 +182,8 @@ app_run (const gchar         *full_prog_name,
   GFile              *default_folder = NULL;
   GFile              *gimpdir;
   const gchar        *abort_message;
+  GimpLangRc         *temprc;
+  gchar              *language = NULL;
 
   if (filenames && filenames[0] && ! filenames[1] &&
       g_file_test (filenames[0], G_FILE_TEST_IS_DIR))
@@ -202,6 +205,26 @@ app_run (const gchar         *full_prog_name,
       filenames = NULL;
     }
 
+  /* Language needs to be determined first, before any GimpContext is
+   * instanciated (which happens when the Gimp object is created)
+   * because its properties need to be properly localized in the
+   * settings language (if different from system language). Otherwise we
+   * end up with pieces of GUI always using the system language (cf. bug
+   * 787457). Therefore we do a first pass on "gimprc" file for the sole
+   * purpose of getting the settings language, so that we can initialize
+   * it before anything else.
+   */
+  temprc = gimp_lang_rc_new (alternate_system_gimprc,
+                             alternate_gimprc,
+                             be_verbose);
+  language = gimp_lang_rc_get_language (temprc);
+  g_object_unref (temprc);
+
+  /*  change the locale if a language if specified  */
+  language_init (language);
+  if (language)
+    g_free (language);
+
   /*  Create an instance of the "Gimp" object which is the root of the
    *  core object system
    */
@@ -252,9 +275,6 @@ app_run (const gchar         *full_prog_name,
 
   gimp_load_config (gimp, alternate_system_gimprc, alternate_gimprc);
 
-  /*  change the locale if a language if specified  */
-  language_init (gimp->config->language);
-
   /*  run the late-stage sanity check.  it's important that this check is run
    *  after the call to language_init() (see comment in sanity_check_late().)
    */
diff --git a/app/config/Makefile.am b/app/config/Makefile.am
index 13d9221..daa949f 100644
--- a/app/config/Makefile.am
+++ b/app/config/Makefile.am
@@ -50,6 +50,8 @@ libappconfig_a_sources = \
        gimpgeglconfig.h                \
        gimpguiconfig.c                 \
        gimpguiconfig.h                 \
+       gimplangrc.c                    \
+       gimplangrc.h                    \
        gimppluginconfig.c              \
        gimppluginconfig.h              \
        gimprc.c                        \
diff --git a/app/config/config-types.h b/app/config/config-types.h
index b672cd5..2bbb79f 100644
--- a/app/config/config-types.h
+++ b/app/config/config-types.h
@@ -36,6 +36,7 @@ typedef struct _GimpCoreConfig       GimpCoreConfig;
 typedef struct _GimpDisplayConfig    GimpDisplayConfig;
 typedef struct _GimpGuiConfig        GimpGuiConfig;
 typedef struct _GimpDialogConfig     GimpDialogConfig;
+typedef struct _GimpLangRc           GimpLangRc;
 typedef struct _GimpPluginConfig     GimpPluginConfig;
 typedef struct _GimpRc               GimpRc;
 
diff --git a/app/config/gimplangrc.c b/app/config/gimplangrc.c
new file mode 100644
index 0000000..c33e5a5
--- /dev/null
+++ b/app/config/gimplangrc.c
@@ -0,0 +1,285 @@
+/* GIMP - The GNU Image Manipulation Program
+ * Copyright (C) 1995 Spencer Kimball and Peter Mattis
+ *
+ * GimpLangRc: pre-parsing of gimprc returning the language.
+ * Copyright (C) 2017  Jehan <jehan gimp org>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "config.h"
+
+#include <gio/gio.h>
+
+#include "libgimpbase/gimpbase.h"
+#include "libgimpconfig/gimpconfig.h"
+
+#include "config-types.h"
+
+#include "gimplangrc.h"
+
+enum
+{
+  PROP_0,
+  PROP_VERBOSE,
+  PROP_SYSTEM_GIMPRC,
+  PROP_USER_GIMPRC,
+  PROP_LANGUAGE
+};
+
+
+static void         gimp_lang_rc_constructed       (GObject      *object);
+static void         gimp_lang_rc_finalize          (GObject      *object);
+static void         gimp_lang_rc_set_property      (GObject      *object,
+                                                    guint         property_id,
+                                                    const GValue *value,
+                                                    GParamSpec   *pspec);
+static void         gimp_lang_rc_get_property      (GObject      *object,
+                                                    guint         property_id,
+                                                    GValue       *value,
+                                                    GParamSpec   *pspec);
+
+
+/* Just use GimpConfig interface's default implementation which will
+ * fill the PROP_LANGUAGE property. */
+G_DEFINE_TYPE_WITH_CODE (GimpLangRc, gimp_lang_rc, G_TYPE_OBJECT,
+                         G_IMPLEMENT_INTERFACE (GIMP_TYPE_CONFIG, NULL))
+
+#define parent_class gimp_lang_rc_parent_class
+
+
+static void
+gimp_lang_rc_class_init (GimpLangRcClass *klass)
+{
+  GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+  object_class->constructed  = gimp_lang_rc_constructed;
+  object_class->finalize     = gimp_lang_rc_finalize;
+  object_class->set_property = gimp_lang_rc_set_property;
+  object_class->get_property = gimp_lang_rc_get_property;
+
+  g_object_class_install_property (object_class, PROP_VERBOSE,
+                                   g_param_spec_boolean ("verbose",
+                                                         NULL, NULL,
+                                                         FALSE,
+                                                         G_PARAM_READWRITE |
+                                                         G_PARAM_CONSTRUCT_ONLY));
+
+  g_object_class_install_property (object_class, PROP_SYSTEM_GIMPRC,
+                                   g_param_spec_object ("system-gimprc",
+                                                        NULL, NULL,
+                                                        G_TYPE_FILE,
+                                                        G_PARAM_READWRITE |
+                                                        G_PARAM_CONSTRUCT_ONLY));
+
+  g_object_class_install_property (object_class, PROP_USER_GIMPRC,
+                                   g_param_spec_object ("user-gimprc",
+                                                        NULL, NULL,
+                                                        G_TYPE_FILE,
+                                                        G_PARAM_READWRITE |
+                                                        G_PARAM_CONSTRUCT_ONLY));
+
+  GIMP_CONFIG_PROP_STRING (object_class, PROP_LANGUAGE,
+                           "language", NULL, NULL, NULL,
+                           GIMP_PARAM_STATIC_STRINGS);
+
+}
+
+static void
+gimp_lang_rc_init (GimpLangRc *rc)
+{
+}
+
+static void
+gimp_lang_rc_constructed (GObject *object)
+{
+  GimpLangRc *rc = GIMP_LANG_RC (object);
+  GError     *error = NULL;
+
+  if (rc->verbose)
+    g_print ("Parsing '%s' for configured language.\n",
+             gimp_file_get_utf8_name (rc->system_gimprc));
+
+  if (! gimp_config_deserialize_gfile (GIMP_CONFIG (rc),
+                                       rc->system_gimprc, NULL, &error))
+    {
+      if (error->code != GIMP_CONFIG_ERROR_OPEN_ENOENT)
+        g_message ("%s", error->message);
+
+      g_clear_error (&error);
+    }
+
+  if (rc->verbose)
+    g_print ("Parsing '%s' for configured language.\n",
+             gimp_file_get_utf8_name (rc->user_gimprc));
+
+  if (! gimp_config_deserialize_gfile (GIMP_CONFIG (rc),
+                                       rc->user_gimprc, NULL, &error))
+    {
+      if (error->code != GIMP_CONFIG_ERROR_OPEN_ENOENT)
+        g_message ("%s", error->message);
+
+      g_clear_error (&error);
+    }
+
+  if (rc->verbose)
+    {
+      if (rc->language)
+        g_print ("Language property found: %s.\n", rc->language);
+      else
+        g_print ("No language property found.\n");
+    }
+}
+
+static void
+gimp_lang_rc_finalize (GObject *object)
+{
+  GimpLangRc *rc = GIMP_LANG_RC (object);
+
+  g_clear_object (&rc->system_gimprc);
+  g_clear_object (&rc->user_gimprc);
+  if (rc->language)
+    {
+      g_free (rc->language);
+      rc->language = NULL;
+    }
+
+  G_OBJECT_CLASS (parent_class)->finalize (object);
+}
+
+static void
+gimp_lang_rc_set_property (GObject      *object,
+                           guint         property_id,
+                           const GValue *value,
+                           GParamSpec   *pspec)
+{
+  GimpLangRc *rc = GIMP_LANG_RC (object);
+
+  switch (property_id)
+    {
+    case PROP_VERBOSE:
+      rc->verbose = g_value_get_boolean (value);
+      break;
+
+    case PROP_SYSTEM_GIMPRC:
+      if (rc->system_gimprc)
+        g_object_unref (rc->system_gimprc);
+
+      if (g_value_get_object (value))
+        rc->system_gimprc = g_value_dup_object (value);
+      else
+        rc->system_gimprc = gimp_sysconf_directory_file ("gimprc", NULL);
+      break;
+
+    case PROP_USER_GIMPRC:
+      if (rc->user_gimprc)
+        g_object_unref (rc->user_gimprc);
+
+      if (g_value_get_object (value))
+        rc->user_gimprc = g_value_dup_object (value);
+      else
+        rc->user_gimprc = gimp_directory_file ("gimprc", NULL);
+      break;
+
+    case PROP_LANGUAGE:
+      if (rc->language)
+        g_free (rc->language);
+      rc->language = g_value_dup_string (value);
+      break;
+
+   default:
+      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+      break;
+    }
+}
+
+static void
+gimp_lang_rc_get_property (GObject    *object,
+                           guint       property_id,
+                           GValue     *value,
+                           GParamSpec *pspec)
+{
+  GimpLangRc *rc = GIMP_LANG_RC (object);
+
+  switch (property_id)
+    {
+    case PROP_VERBOSE:
+      g_value_set_boolean (value, rc->verbose);
+      break;
+    case PROP_SYSTEM_GIMPRC:
+      g_value_set_object (value, rc->system_gimprc);
+      break;
+    case PROP_USER_GIMPRC:
+      g_value_set_object (value, rc->user_gimprc);
+      break;
+    case PROP_LANGUAGE:
+      g_value_set_string (value, rc->language);
+      break;
+
+   default:
+      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+      break;
+    }
+}
+
+/**
+ * gimp_lang_rc_new:
+ * @system_gimprc: the name of the system-wide gimprc file or %NULL to
+ *                 use the standard location
+ * @user_gimprc:   the name of the user gimprc file or %NULL to use the
+ *                 standard location
+ * @verbose:       enable console messages about loading the language
+ *
+ * Creates a new GimpLangRc object which only looks for the configure
+ * language.
+ *
+ * Returns: the new #GimpLangRc.
+ */
+GimpLangRc *
+gimp_lang_rc_new (GFile    *system_gimprc,
+                  GFile    *user_gimprc,
+                  gboolean  verbose)
+{
+  GimpLangRc *rc;
+
+  g_return_val_if_fail (system_gimprc == NULL || G_IS_FILE (system_gimprc),
+                        NULL);
+  g_return_val_if_fail (user_gimprc == NULL || G_IS_FILE (user_gimprc),
+                        NULL);
+
+  rc = g_object_new (GIMP_TYPE_LANG_RC,
+                     "verbose",       verbose,
+                     "system-gimprc", system_gimprc,
+                     "user-gimprc",   user_gimprc,
+                     NULL);
+
+  return rc;
+}
+
+/**
+ * gimp_lang_rc_get_language:
+ * @lang_rc:  a #GimpLangRc object.
+ *
+ * This function looks up the language set in `gimprc`.
+ * If no language property is found, the list of unknown tokens
+ * attached to the @rc object is searched.
+ *
+ * Return value: a newly allocated string representing the language or
+ *               %NULL if the key couldn't be found.
+ **/
+gchar *
+gimp_lang_rc_get_language (GimpLangRc *rc)
+{
+  return rc->language ? g_strdup (rc->language) : NULL;
+}
diff --git a/app/config/gimplangrc.h b/app/config/gimplangrc.h
new file mode 100644
index 0000000..9d2eef7
--- /dev/null
+++ b/app/config/gimplangrc.h
@@ -0,0 +1,60 @@
+/* GIMP - The GNU Image Manipulation Program
+ * Copyright (C) 1995 Spencer Kimball and Peter Mattis
+ *
+ * GimpLangRc: pre-parsing of gimprc returning the language.
+ * Copyright (C) 2017  Jehan <jehan gimp org>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef __GIMP_LANG_RC_H__
+#define __GIMP_LANG_RC_H__
+
+
+#define GIMP_TYPE_LANG_RC            (gimp_lang_rc_get_type ())
+#define GIMP_LANG_RC(obj)            (G_TYPE_CHECK_INSTANCE_CAST ((obj), GIMP_TYPE_LANG_RC, GimpLangRc))
+#define GIMP_LANG_RC_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST ((klass), GIMP_TYPE_LANG_RC, GimpLangRcClass))
+#define GIMP_IS_LANG_RC(obj)         (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GIMP_TYPE_LANG_RC))
+#define GIMP_IS_LANG_RC_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GIMP_TYPE_LANG_RC))
+
+
+typedef struct _GimpLangRcClass GimpLangRcClass;
+
+struct _GimpLangRc
+{
+  GObject        parent_instance;
+
+  GFile         *user_gimprc;
+  GFile         *system_gimprc;
+  gboolean       verbose;
+
+  gchar         *language;
+};
+
+struct _GimpLangRcClass
+{
+  GObjectClass   parent_class;
+};
+
+
+GType         gimp_lang_rc_get_type     (void) G_GNUC_CONST;
+
+GimpLangRc  * gimp_lang_rc_new          (GFile      *system_gimprc,
+                                         GFile      *user_gimprc,
+                                         gboolean    verbose);
+gchar       * gimp_lang_rc_get_language (GimpLangRc *rc);
+
+
+#endif /* GIMP_LANG_RC_H__ */
+


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]