[gnome-shell] theme: convert stylesheet loading to GFile



commit 642bf2b778281905e61db824731acdd59521e879
Author: Cosimo Cecchi <cosimoc gnome org>
Date:   Thu Sep 18 19:22:02 2014 -0700

    theme: convert stylesheet loading to GFile
    
    In preparation to making it a GResource.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=736936

 js/ui/extensionSystem.js |    4 +-
 js/ui/main.js            |    6 +-
 src/st/st-theme.c        |  181 +++++++++++++++++++++++++---------------------
 src/st/st-theme.h        |   10 ++--
 src/st/test-theme.c      |    6 +-
 tests/testcommon/ui.js   |    3 +-
 6 files changed, 113 insertions(+), 97 deletions(-)
---
diff --git a/js/ui/extensionSystem.js b/js/ui/extensionSystem.js
index 11a75c6..fac21bf 100644
--- a/js/ui/extensionSystem.js
+++ b/js/ui/extensionSystem.js
@@ -74,7 +74,7 @@ function disableExtension(uuid) {
 
     if (extension.stylesheet) {
         let theme = St.ThemeContext.get_for_stage(global.stage).get_theme();
-        theme.unload_stylesheet(extension.stylesheet.get_path());
+        theme.unload_stylesheet(extension.stylesheet);
     }
 
     try {
@@ -118,7 +118,7 @@ function enableExtension(uuid) {
         let stylesheetFile = extension.dir.get_child(stylesheetNames[i]);
         if (stylesheetFile.query_exists(null)) {
             let theme = St.ThemeContext.get_for_stage(global.stage).get_theme();
-            theme.load_stylesheet(stylesheetFile.get_path());
+            theme.load_stylesheet(stylesheetFile);
             extension.stylesheet = stylesheetFile;
             break;
         }
diff --git a/js/ui/main.js b/js/ui/main.js
index f9bb59e..994bbe4 100644
--- a/js/ui/main.js
+++ b/js/ui/main.js
@@ -228,8 +228,8 @@ function _loadDefaultStylesheet() {
     if (!sessionMode.isPrimary)
         return;
 
-    let stylesheet = global.datadir + '/theme/' + sessionMode.stylesheetName;
-    if (_defaultCssStylesheet == stylesheet)
+    let stylesheet = Gio.File.new_for_path(global.datadir + '/theme/' + sessionMode.stylesheetName);
+    if (_defaultCssStylesheet && _defaultCssStylesheet.equal(stylesheet))
         return;
 
     _defaultCssStylesheet = stylesheet;
@@ -256,7 +256,7 @@ function getThemeStylesheet() {
  * Set the theme CSS file that the shell will load
  */
 function setThemeStylesheet(cssStylesheet) {
-    _cssStylesheet = cssStylesheet;
+    _cssStylesheet = Gio.File.new_for_path(cssStylesheet);
 }
 
 /**
diff --git a/src/st/st-theme.c b/src/st/st-theme.c
index 7eca7f8..2dab983 100644
--- a/src/st/st-theme.c
+++ b/src/st/st-theme.c
@@ -60,13 +60,13 @@ struct _StTheme
 {
   GObject parent;
 
-  char *application_stylesheet;
-  char *default_stylesheet;
-  char *theme_stylesheet;
+  GFile *application_stylesheet;
+  GFile *default_stylesheet;
+  GFile *theme_stylesheet;
   GSList *custom_stylesheets;
 
-  GHashTable *stylesheets_by_filename;
-  GHashTable *filenames_by_stylesheet;
+  GHashTable *stylesheets_by_file;
+  GHashTable *files_by_stylesheet;
 
   CRCascade *cascade;
 };
@@ -98,12 +98,25 @@ G_DEFINE_TYPE (StTheme, st_theme, G_TYPE_OBJECT)
 #define strqcmp(str,lit,lit_len) \
   (strlen (str) != (lit_len) || memcmp (str, lit, lit_len))
 
+static gboolean
+file_equal0 (GFile *file1,
+             GFile *file2)
+{
+  if (file1 == file2)
+    return TRUE;
+
+  if ((file1 == NULL) || (file2 == NULL))
+    return FALSE;
+
+  return g_file_equal (file1, file2);
+}
+
 static void
 st_theme_init (StTheme *theme)
 {
-  theme->stylesheets_by_filename = g_hash_table_new_full (g_str_hash, g_str_equal,
-                                                          (GDestroyNotify)g_free, 
(GDestroyNotify)cr_stylesheet_unref);
-  theme->filenames_by_stylesheet = g_hash_table_new (g_direct_hash, g_direct_equal);
+  theme->stylesheets_by_file = g_hash_table_new_full (g_file_hash, (GEqualFunc) g_file_equal,
+                                                      (GDestroyNotify)g_object_unref, 
(GDestroyNotify)cr_stylesheet_unref);
+  theme->files_by_stylesheet = g_hash_table_new (g_direct_hash, g_direct_equal);
 }
 
 static void
@@ -124,10 +137,10 @@ st_theme_class_init (StThemeClass *klass)
    */
   g_object_class_install_property (object_class,
                                    PROP_APPLICATION_STYLESHEET,
-                                   g_param_spec_string ("application-stylesheet",
+                                   g_param_spec_object ("application-stylesheet",
                                                         "Application Stylesheet",
                                                         "Stylesheet with application-specific styling",
-                                                        NULL,
+                                                        G_TYPE_FILE,
                                                         G_PARAM_READABLE | G_PARAM_WRITABLE | 
G_PARAM_CONSTRUCT_ONLY));
 
   /**
@@ -138,10 +151,10 @@ st_theme_class_init (StThemeClass *klass)
    */
   g_object_class_install_property (object_class,
                                    PROP_THEME_STYLESHEET,
-                                   g_param_spec_string ("theme-stylesheet",
+                                   g_param_spec_object ("theme-stylesheet",
                                                         "Theme Stylesheet",
                                                         "Stylesheet with theme-specific styling",
-                                                        NULL,
+                                                        G_TYPE_FILE,
                                                         G_PARAM_READABLE | G_PARAM_WRITABLE | 
G_PARAM_CONSTRUCT_ONLY));
 
   /**
@@ -152,10 +165,10 @@ st_theme_class_init (StThemeClass *klass)
    */
   g_object_class_install_property (object_class,
                                    PROP_DEFAULT_STYLESHEET,
-                                   g_param_spec_string ("default-stylesheet",
+                                   g_param_spec_object ("default-stylesheet",
                                                         "Default Stylesheet",
                                                         "Stylesheet with global default styling",
-                                                        NULL,
+                                                        G_TYPE_FILE,
                                                         G_PARAM_READABLE | G_PARAM_WRITABLE | 
G_PARAM_CONSTRUCT_ONLY));
 
   signals[STYLESHEETS_CHANGED] =
@@ -168,23 +181,32 @@ st_theme_class_init (StThemeClass *klass)
 }
 
 static CRStyleSheet *
-parse_stylesheet (const char  *filename,
-                  GError     **error)
+parse_stylesheet (GFile   *file,
+                  GError **error)
 {
   enum CRStatus status;
   CRStyleSheet *stylesheet;
+  char *contents;
+  gsize length;
 
-  if (filename == NULL)
+  if (file == NULL)
     return NULL;
 
-  status = cr_om_parser_simply_parse_file ((const guchar *) filename,
-                                           CR_UTF_8,
-                                           &stylesheet);
+  if (!g_file_load_contents (file, NULL, &contents, &length, NULL, error))
+    return NULL;
+
+  status = cr_om_parser_simply_parse_buf ((const guchar *) contents,
+                                          length,
+                                          CR_UTF_8,
+                                          &stylesheet);
+  g_free (contents);
 
   if (status != CR_OK)
     {
+      char *uri = g_file_get_uri (file);
       g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
-                   "Error parsing stylesheet '%s'; errcode:%d", filename, status);
+                   "Error parsing stylesheet '%s'; errcode:%d", uri, status);
+      g_free (uri);
       return NULL;
     }
 
@@ -203,12 +225,12 @@ _st_theme_parse_declaration_list (const char *str)
 
 /* Just g_warning for now until we have something nicer to do */
 static CRStyleSheet *
-parse_stylesheet_nofail (const char *filename)
+parse_stylesheet_nofail (GFile *file)
 {
   GError *error = NULL;
   CRStyleSheet *result;
 
-  result = parse_stylesheet (filename, &error);
+  result = parse_stylesheet (file, &error);
   if (error)
     {
       g_warning ("%s", error->message);
@@ -219,35 +241,33 @@ parse_stylesheet_nofail (const char *filename)
 
 static void
 insert_stylesheet (StTheme      *theme,
-                   const char   *filename,
+                   GFile        *file,
                    CRStyleSheet *stylesheet)
 {
-  char *filename_copy;
-
   if (stylesheet == NULL)
     return;
 
-  filename_copy = g_strdup(filename);
+  g_object_ref (file);
   cr_stylesheet_ref (stylesheet);
 
-  g_hash_table_insert (theme->stylesheets_by_filename, filename_copy, stylesheet);
-  g_hash_table_insert (theme->filenames_by_stylesheet, stylesheet, filename_copy);
+  g_hash_table_insert (theme->stylesheets_by_file, file, stylesheet);
+  g_hash_table_insert (theme->files_by_stylesheet, stylesheet, file);
 }
 
 gboolean
 st_theme_load_stylesheet (StTheme    *theme,
-                          const char *path,
+                          GFile      *file,
                           GError    **error)
 {
   CRStyleSheet *stylesheet;
 
-  stylesheet = parse_stylesheet (path, error);
+  stylesheet = parse_stylesheet (file, error);
   if (!stylesheet)
     return FALSE;
 
   stylesheet->app_data = GUINT_TO_POINTER (TRUE);
 
-  insert_stylesheet (theme, path, stylesheet);
+  insert_stylesheet (theme, file, stylesheet);
   cr_stylesheet_ref (stylesheet);
   theme->custom_stylesheets = g_slist_prepend (theme->custom_stylesheets, stylesheet);
   g_signal_emit (theme, signals[STYLESHEETS_CHANGED], 0);
@@ -257,11 +277,11 @@ st_theme_load_stylesheet (StTheme    *theme,
 
 void
 st_theme_unload_stylesheet (StTheme    *theme,
-                            const char *path)
+                            GFile      *file)
 {
   CRStyleSheet *stylesheet;
 
-  stylesheet = g_hash_table_lookup (theme->stylesheets_by_filename, path);
+  stylesheet = g_hash_table_lookup (theme->stylesheets_by_file, file);
   if (!stylesheet)
     return;
 
@@ -269,8 +289,8 @@ st_theme_unload_stylesheet (StTheme    *theme,
     return;
 
   theme->custom_stylesheets = g_slist_remove (theme->custom_stylesheets, stylesheet);
-  g_hash_table_remove (theme->stylesheets_by_filename, path);
-  g_hash_table_remove (theme->filenames_by_stylesheet, stylesheet);
+  g_hash_table_remove (theme->stylesheets_by_file, file);
+  g_hash_table_remove (theme->files_by_stylesheet, stylesheet);
   cr_stylesheet_unref (stylesheet);
   g_signal_emit (theme, signals[STYLESHEETS_CHANGED], 0);
 }
@@ -279,7 +299,7 @@ st_theme_unload_stylesheet (StTheme    *theme,
  * st_theme_get_custom_stylesheets:
  * @theme: an #StTheme
  *
- * Returns: (transfer full) (element-type utf8): the list of stylesheet filenames
+ * Returns: (transfer full) (element-type GFile): the list of stylesheet files
  *          that were loaded with st_theme_load_stylesheet()
  */
 GSList*
@@ -291,9 +311,9 @@ st_theme_get_custom_stylesheets (StTheme *theme)
   for (iter = theme->custom_stylesheets; iter; iter = iter->next)
     {
       CRStyleSheet *stylesheet = iter->data;
-      gchar *filename = g_hash_table_lookup (theme->filenames_by_stylesheet, stylesheet);
+      GFile *file = g_hash_table_lookup (theme->files_by_stylesheet, stylesheet);
 
-      result = g_slist_prepend (result, g_strdup (filename));
+      result = g_slist_prepend (result, g_object_ref (file));
     }
 
   return result;
@@ -334,12 +354,12 @@ st_theme_finalize (GObject * object)
   g_slist_free (theme->custom_stylesheets);
   theme->custom_stylesheets = NULL;
 
-  g_hash_table_destroy (theme->stylesheets_by_filename);
-  g_hash_table_destroy (theme->filenames_by_stylesheet);
+  g_hash_table_destroy (theme->stylesheets_by_file);
+  g_hash_table_destroy (theme->files_by_stylesheet);
 
-  g_free (theme->application_stylesheet);
-  g_free (theme->theme_stylesheet);
-  g_free (theme->default_stylesheet);
+  g_clear_object (&theme->application_stylesheet);
+  g_clear_object (&theme->theme_stylesheet);
+  g_clear_object (&theme->default_stylesheet);
 
   if (theme->cascade)
     {
@@ -362,36 +382,39 @@ st_theme_set_property (GObject      *object,
     {
     case PROP_APPLICATION_STYLESHEET:
       {
-        const char *path = g_value_get_string (value);
+        GFile *file = g_value_get_object (value);
 
-        if (path != theme->application_stylesheet)
+        if (!file_equal0 (file, theme->application_stylesheet))
           {
-            g_free (theme->application_stylesheet);
-            theme->application_stylesheet = g_strdup (path);
+            g_clear_object (&theme->application_stylesheet);
+            if (file != NULL)
+              theme->application_stylesheet = g_object_ref (file);
           }
 
         break;
       }
     case PROP_THEME_STYLESHEET:
       {
-        const char *path = g_value_get_string (value);
+        GFile *file = g_value_get_object (value);
 
-        if (path != theme->theme_stylesheet)
+        if (!file_equal0 (file, theme->theme_stylesheet))
           {
-            g_free (theme->theme_stylesheet);
-            theme->theme_stylesheet = g_strdup (path);
+            g_clear_object (&theme->theme_stylesheet);
+            if (file != NULL)
+              theme->theme_stylesheet = g_object_ref (file);
           }
 
         break;
       }
     case PROP_DEFAULT_STYLESHEET:
       {
-        const char *path = g_value_get_string (value);
+        GFile *file = g_value_get_object (value);
 
-        if (path != theme->default_stylesheet)
+        if (!file_equal0 (file, theme->default_stylesheet))
           {
-            g_free (theme->default_stylesheet);
-            theme->default_stylesheet = g_strdup (path);
+            g_clear_object (&theme->default_stylesheet);
+            if (file != NULL)
+              theme->default_stylesheet = g_object_ref (file);
           }
 
         break;
@@ -413,13 +436,13 @@ st_theme_get_property (GObject    *object,
   switch (prop_id)
     {
     case PROP_APPLICATION_STYLESHEET:
-      g_value_set_string (value, theme->application_stylesheet);
+      g_value_set_object (value, theme->application_stylesheet);
       break;
     case PROP_THEME_STYLESHEET:
-      g_value_set_string (value, theme->theme_stylesheet);
+      g_value_set_object (value, theme->theme_stylesheet);
       break;
     case PROP_DEFAULT_STYLESHEET:
-      g_value_set_string (value, theme->default_stylesheet);
+      g_value_set_object (value, theme->default_stylesheet);
       break;
     default:
       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
@@ -439,9 +462,9 @@ st_theme_get_property (GObject    *object,
  * Return value: the newly created theme object
  **/
 StTheme *
-st_theme_new (const char       *application_stylesheet,
-              const char       *theme_stylesheet,
-              const char       *default_stylesheet)
+st_theme_new (GFile       *application_stylesheet,
+              GFile       *theme_stylesheet,
+              GFile       *default_stylesheet)
 {
   StTheme *theme = g_object_new (ST_TYPE_THEME,
                                     "application-stylesheet", application_stylesheet,
@@ -852,26 +875,19 @@ add_matched_properties (StTheme      *a_this,
 
             if (import_rule->sheet == NULL)
               {
-                char *filename = NULL;
+                GFile *file = NULL;
 
                 if (import_rule->url->stryng && import_rule->url->stryng->str)
                   {
-                    GFile *file;
-
                     file = _st_theme_resolve_url (a_this,
                                                   a_nodesheet,
                                                   import_rule->url->stryng->str);
-                    filename = g_file_get_path (file);
-
-                    g_object_unref (file);
+                    import_rule->sheet = parse_stylesheet (file, NULL);
                   }
 
-                if (filename)
-                  import_rule->sheet = parse_stylesheet (filename, NULL);
-
                 if (import_rule->sheet)
                   {
-                    insert_stylesheet (a_this, filename, import_rule->sheet);
+                    insert_stylesheet (a_this, file, import_rule->sheet);
                     /* refcount of stylesheets starts off at zero, so we don't need to unref! */
                   }
                 else
@@ -882,8 +898,8 @@ add_matched_properties (StTheme      *a_this,
                     import_rule->sheet = (CRStyleSheet *) - 1;
                   }
 
-                if (filename)
-                  g_free (filename);
+                if (file)
+                  g_object_unref (file);
               }
 
             if (import_rule->sheet != (CRStyleSheet *) - 1)
@@ -1018,7 +1034,7 @@ _st_theme_resolve_url (StTheme      *theme,
                        const char   *url)
 {
   char *scheme;
-  GFile *stylesheet, *resource;
+  GFile *resource;
 
   if ((scheme = g_uri_parse_scheme (url)))
     {
@@ -1027,21 +1043,18 @@ _st_theme_resolve_url (StTheme      *theme,
     }
   else if (base_stylesheet != NULL)
     {
-      const char *base_filename = NULL;
-      char *dirname;
+      GFile *base_file = NULL, *parent;
 
-      base_filename = g_hash_table_lookup (theme->filenames_by_stylesheet, base_stylesheet);
+      base_file = g_hash_table_lookup (theme->files_by_stylesheet, base_stylesheet);
 
       /* This is an internal function, if we get here with
          a bad @base_stylesheet we have a problem. */
-      g_assert (base_filename);
+      g_assert (base_file);
 
-      dirname = g_path_get_dirname (base_filename);
-      stylesheet = g_file_new_for_path (dirname);
-      resource = g_file_resolve_relative_path (stylesheet, url);
+      parent = g_file_get_parent (base_file);
+      resource = g_file_resolve_relative_path (parent, url);
 
-      g_object_unref (stylesheet);
-      g_free (dirname);
+      g_object_unref (parent);
     }
   else
     {
diff --git a/src/st/st-theme.h b/src/st/st-theme.h
index eb0103f..b6dee04 100644
--- a/src/st/st-theme.h
+++ b/src/st/st-theme.h
@@ -47,12 +47,12 @@ typedef struct _StThemeClass StThemeClass;
 
 GType  st_theme_get_type (void) G_GNUC_CONST;
 
-StTheme *st_theme_new (const char *application_stylesheet,
-                       const char *theme_stylesheet,
-                       const char *default_stylesheet);
+StTheme *st_theme_new (GFile *application_stylesheet,
+                       GFile *theme_stylesheet,
+                       GFile *default_stylesheet);
 
-gboolean  st_theme_load_stylesheet        (StTheme *theme, const char *path, GError **error);
-void      st_theme_unload_stylesheet      (StTheme *theme, const char *path);
+gboolean  st_theme_load_stylesheet        (StTheme *theme, GFile *file, GError **error);
+void      st_theme_unload_stylesheet      (StTheme *theme, GFile *file);
 GSList   *st_theme_get_custom_stylesheets (StTheme *theme);
 
 G_END_DECLS
diff --git a/src/st/test-theme.c b/src/st/test-theme.c
index 6e7f211..5fa5de3 100644
--- a/src/st/test-theme.c
+++ b/src/st/test-theme.c
@@ -430,14 +430,16 @@ main (int argc, char **argv)
   StTheme *theme;
   StThemeContext *context;
   PangoFontDescription *font_desc;
+  GFile *file;
 
   gtk_init (&argc, &argv);
 
   if (clutter_init (&argc, &argv) != CLUTTER_INIT_SUCCESS)
     return 1;
 
-  theme = st_theme_new ("st/test-theme.css",
-                        NULL, NULL);
+  file = g_file_new_for_path ("st/test-theme.css");
+  theme = st_theme_new (file, NULL, NULL);
+  g_object_unref (file);
 
   stage = clutter_stage_new ();
   context = st_theme_context_get_for_stage (CLUTTER_STAGE (stage));
diff --git a/tests/testcommon/ui.js b/tests/testcommon/ui.js
index 4813d76..b66b0cd 100644
--- a/tests/testcommon/ui.js
+++ b/tests/testcommon/ui.js
@@ -1,6 +1,7 @@
 // -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
 
 const Clutter = imports.gi.Clutter;
+const Gio = imports.gi.Gio;
 const GLib = imports.gi.GLib;
 const St = imports.gi.St;
 
@@ -10,7 +11,7 @@ function init(stage) {
     Environment.init();
     let context = St.ThemeContext.get_for_stage(stage);
     let stylesheetPath = GLib.getenv("GNOME_SHELL_TESTSDIR") + "/testcommon/test.css";
-    let theme = new St.Theme({ application_stylesheet: stylesheetPath });
+    let theme = new St.Theme({ application_stylesheet: Gio.File.new_for_path(stylesheetPath) });
     context.set_theme(theme);
 }
 


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