[gtk+] cssprovider: Store sections with parsed values



commit 0d1b73f8570499da9eecea8136bcd6ea519a0d84
Author: Benjamin Otte <otte redhat com>
Date:   Fri Jun 17 05:58:04 2011 +0200

    cssprovider: Store sections with parsed values
    
    Also create a separate section for values to associate the values with.
    Finally, use this section information when delayed-parsing a widget
    style property.

 gtk/gtkcssprovider.c |  118 +++++++++++++++++++++++++++++---------------------
 gtk/gtkcsssection.h  |    2 +
 2 files changed, 70 insertions(+), 50 deletions(-)
---
diff --git a/gtk/gtkcssprovider.c b/gtk/gtkcssprovider.c
index acc0e30..996fe9d 100644
--- a/gtk/gtkcssprovider.c
+++ b/gtk/gtkcssprovider.c
@@ -1148,19 +1148,39 @@ gtk_css_ruleset_clear (GtkCssRuleset *ruleset)
   memset (ruleset, 0, sizeof (GtkCssRuleset));
 }
 
+typedef struct _PropertyValue PropertyValue;
+struct _PropertyValue {
+  GtkCssSection *section;
+  GValue         value;
+};
+
+static PropertyValue *
+property_value_new (GtkCssSection *section)
+{
+  PropertyValue *value;
+
+  value = g_slice_new0 (PropertyValue);
+
+  value->section = gtk_css_section_ref (section);
+
+  return value;
+}
+
 static void
-property_value_free (GValue *value)
+property_value_free (PropertyValue *value)
 {
-  if (G_IS_VALUE (value))
-    g_value_unset (value);
+  if (G_IS_VALUE (&value->value))
+    g_value_unset (&value->value);
+
+  gtk_css_section_unref (value->section);
 
-  g_slice_free (GValue, value);
+  g_slice_free (PropertyValue, value);
 }
 
 static void
 gtk_css_ruleset_add_style (GtkCssRuleset *ruleset,
                            char          *name,
-                           GValue        *value)
+                           PropertyValue *value)
 {
   if (ruleset->widget_style == NULL)
     ruleset->widget_style = g_hash_table_new_full (g_str_hash,
@@ -1174,7 +1194,7 @@ gtk_css_ruleset_add_style (GtkCssRuleset *ruleset,
 static void
 gtk_css_ruleset_add (GtkCssRuleset          *ruleset,
                      const GtkStyleProperty *prop,
-                     GValue                 *value)
+                     PropertyValue          *value)
 {
   if (ruleset->style == NULL)
     ruleset->style = g_hash_table_new_full (g_direct_hash,
@@ -1187,16 +1207,17 @@ gtk_css_ruleset_add (GtkCssRuleset          *ruleset,
       GParameter *parameters;
       guint i, n_parameters;
 
-      parameters = _gtk_style_property_unpack (prop, value, &n_parameters);
+      parameters = _gtk_style_property_unpack (prop, &value->value, &n_parameters);
 
       for (i = 0; i < n_parameters; i++)
         {
           const GtkStyleProperty *child;
-          GValue *value;
+          PropertyValue *val;
 
           child = _gtk_style_property_lookup (parameters[i].name);
-          value = g_slice_dup (GValue, &parameters[i].value);
-          gtk_css_ruleset_add (ruleset, child, value);
+          val = property_value_new (value->section);
+          memcpy (&val->value, &parameters[i].value, sizeof (GValue));
+          gtk_css_ruleset_add (ruleset, child, val);
         }
       g_free (parameters);
       property_value_free (value);
@@ -1393,7 +1414,7 @@ gtk_css_provider_get_style (GtkStyleProvider *provider,
         {
           GtkCssRuleset *ruleset;
           GHashTableIter iter;
-          gpointer key, value;
+          gpointer key, val;
 
           ruleset = &g_array_index (priv->rulesets, GtkCssRuleset, i);
 
@@ -1408,9 +1429,10 @@ gtk_css_provider_get_style (GtkStyleProvider *provider,
 
           g_hash_table_iter_init (&iter, ruleset->style);
 
-          while (g_hash_table_iter_next (&iter, &key, &value))
+          while (g_hash_table_iter_next (&iter, &key, &val))
             {
               GtkStyleProperty *prop = key;
+              PropertyValue *value = val;
 
               if (l != length && !_gtk_style_property_is_inherit (prop))
                 continue;
@@ -1418,7 +1440,7 @@ gtk_css_provider_get_style (GtkStyleProvider *provider,
               _gtk_style_properties_set_property_by_property (props,
                                                               prop,
                                                               _gtk_css_selector_get_state_flags (ruleset->selector),
-                                                              value);
+                                                              &value->value);
             }
         }
     }
@@ -1426,20 +1448,6 @@ gtk_css_provider_get_style (GtkStyleProvider *provider,
   return props;
 }
 
-static void
-gtk_css_provider_parser_error (GtkCssParser *parser,
-                               const GError *error,
-                               gpointer      user_data)
-{
-  GtkCssProvider *provider = user_data;
-
-  gtk_css_provider_take_error_full (provider,
-                                    NULL,
-                                    _gtk_css_parser_get_line (parser),
-                                    _gtk_css_parser_get_position (parser),
-                                    g_error_copy (error));
-}
-
 static gboolean
 gtk_css_provider_get_style_property (GtkStyleProvider *provider,
                                      GtkWidgetPath    *path,
@@ -1449,7 +1457,7 @@ gtk_css_provider_get_style_property (GtkStyleProvider *provider,
 {
   GtkCssProvider *css_provider = GTK_CSS_PROVIDER (provider);
   GtkCssProviderPrivate *priv = css_provider->priv;
-  const GValue *val;
+  PropertyValue *val;
   gboolean found = FALSE;
   gchar *prop_name;
   gint i;
@@ -1480,18 +1488,20 @@ gtk_css_provider_get_style_property (GtkStyleProvider *provider,
            ((selector_state & state) != 0 &&
             (selector_state & ~(state)) == 0)))
         {
-          GtkCssParser *parser;
+          GtkCssScanner *scanner;
 
-          parser = _gtk_css_parser_new (g_value_get_string (val),
-                                        gtk_css_provider_parser_error,
-                                        provider);
+          scanner = gtk_css_scanner_new (css_provider,
+                                         NULL,
+                                         val->section,
+                                         gtk_css_section_get_file (val->section),
+                                         g_value_get_string (&val->value));
 
           found = _gtk_style_property_parse_value (NULL,
                                                    value,
-                                                   parser,
+                                                   scanner->parser,
                                                    NULL);
 
-          _gtk_css_parser_free (parser);
+          gtk_css_scanner_destroy (scanner);
 
           if (found)
             break;
@@ -2259,15 +2269,17 @@ parse_declaration (GtkCssScanner *scanner,
 
   if (property)
     {
-      GValue *val;
+      PropertyValue *val;
 
       g_free (name);
 
-      val = g_slice_new0 (GValue);
-      g_value_init (val, property->pspec->value_type);
+      gtk_css_scanner_push_section (scanner, GTK_CSS_SECTION_VALUE);
+
+      val = property_value_new (scanner->section);
+      g_value_init (&val->value, property->pspec->value_type);
 
       if (_gtk_style_property_parse_value (property,
-                                           val,
+                                           &val->value,
                                            scanner->parser,
                                            gtk_css_scanner_get_base_url (scanner)))
         {
@@ -2285,42 +2297,48 @@ parse_declaration (GtkCssScanner *scanner,
                                               GTK_CSS_PROVIDER_ERROR_SYNTAX,
                                               "Junk at end of value");
               _gtk_css_parser_resync (scanner->parser, TRUE, '}');
-              g_value_unset (val);
-              g_slice_free (GValue, val);
+              property_value_free (val);
+              gtk_css_scanner_pop_section (scanner, GTK_CSS_SECTION_VALUE);
               gtk_css_scanner_pop_section (scanner, GTK_CSS_SECTION_DECLARATION);
               return;
             }
         }
       else
         {
-          g_value_unset (val);
-          g_slice_free (GValue, val);
+          property_value_free (val);
           _gtk_css_parser_resync (scanner->parser, TRUE, '}');
+          gtk_css_scanner_pop_section (scanner, GTK_CSS_SECTION_VALUE);
           gtk_css_scanner_pop_section (scanner, GTK_CSS_SECTION_DECLARATION);
           return;
         }
+      gtk_css_scanner_pop_section (scanner, GTK_CSS_SECTION_VALUE);
     }
   else if (name[0] == '-')
     {
       char *value_str;
 
+      gtk_css_scanner_push_section (scanner, GTK_CSS_SECTION_VALUE);
+
       value_str = _gtk_css_parser_read_value (scanner->parser);
       if (value_str)
         {
-          GValue *val;
+          PropertyValue *val;
 
-          val = g_slice_new0 (GValue);
-          g_value_init (val, G_TYPE_STRING);
-          g_value_take_string (val, value_str);
+          val = property_value_new (scanner->section);
+          g_value_init (&val->value, G_TYPE_STRING);
+          g_value_take_string (&val->value, value_str);
 
           gtk_css_ruleset_add_style (ruleset, name, val);
         }
       else
         {
           _gtk_css_parser_resync (scanner->parser, TRUE, '}');
+          gtk_css_scanner_pop_section (scanner, GTK_CSS_SECTION_VALUE);
           gtk_css_scanner_pop_section (scanner, GTK_CSS_SECTION_DECLARATION);
           return;
         }
+
+      gtk_css_scanner_pop_section (scanner, GTK_CSS_SECTION_VALUE);
     }
   else
     g_free (name);
@@ -3174,12 +3192,12 @@ gtk_css_ruleset_print (const GtkCssRuleset *ruleset,
       for (walk = keys; walk; walk = walk->next)
         {
           GtkStyleProperty *prop = walk->data;
-          const GValue *value = g_hash_table_lookup (ruleset->style, prop);
+          const PropertyValue *value = g_hash_table_lookup (ruleset->style, prop);
 
           g_string_append (str, "  ");
           g_string_append (str, prop->pspec->name);
           g_string_append (str, ": ");
-          _gtk_style_property_print_value (prop, value, str);
+          _gtk_style_property_print_value (prop, &value->value, str);
           g_string_append (str, ";\n");
         }
 
@@ -3195,12 +3213,12 @@ gtk_css_ruleset_print (const GtkCssRuleset *ruleset,
       for (walk = keys; walk; walk = walk->next)
         {
           const char *name = walk->data;
-          const GValue *value = g_hash_table_lookup (ruleset->widget_style, (gpointer) name);
+          const PropertyValue *value = g_hash_table_lookup (ruleset->widget_style, (gpointer) name);
 
           g_string_append (str, "  ");
           g_string_append (str, name);
           g_string_append (str, ": ");
-          g_string_append (str, g_value_get_string (value));
+          g_string_append (str, g_value_get_string (&value->value));
           g_string_append (str, ";\n");
         }
 
diff --git a/gtk/gtkcsssection.h b/gtk/gtkcsssection.h
index 761ebd1..06222eb 100644
--- a/gtk/gtkcsssection.h
+++ b/gtk/gtkcsssection.h
@@ -40,6 +40,7 @@ G_BEGIN_DECLS
  * @GTK_CSS_SECTION_SELECTOR: The section defines a CSS selector.
  * @GTK_CSS_SECTION_DECLARATION: The section defines the declaration of
  *   a CSS variable.
+ * @GTK_CSS_SECTION_VALUE: The section defines the value of a CSS declaration.
  *
  * The different types of sections indicate parts of a CSS document as
  * parsed by GTK's CSS parser. They are oriented towards the CSS grammar
@@ -60,6 +61,7 @@ typedef enum
   GTK_CSS_SECTION_RULESET,
   GTK_CSS_SECTION_SELECTOR,
   GTK_CSS_SECTION_DECLARATION,
+  GTK_CSS_SECTION_VALUE
 } GtkCssSectionType;
 
 typedef struct _GtkCssSection GtkCssSection;



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