[gtk+/wip/otte/tokenizer: 55/78] cssdeclaration: Turn into abstract base class



commit 0f9526578aa58c8f3480f1671c0f2923562cb844
Author: Benjamin Otte <otte redhat com>
Date:   Sat Mar 26 03:31:39 2016 +0100

    cssdeclaration: Turn into abstract base class
    
    This is in preparation for allowing to parse style properties like
    -GtkWidget-focus-width.

 gtk/Makefile.am                         |   12 ++-
 gtk/gtkcssdeclaration.c                 |  103 ++++++----------
 gtk/gtkcssdeclarationprivate.h          |   10 ++-
 gtk/gtkcsskeyframes.c                   |   41 +++----
 gtk/gtkcsslonghanddeclaration.c         |  177 +++++++++++++++++++++++++++
 gtk/gtkcsslonghanddeclarationprivate.h  |   62 ++++++++++
 gtk/gtkcssshorthanddeclaration.c        |  203 +++++++++++++++++++++++++++++++
 gtk/gtkcssshorthanddeclarationprivate.h |   64 ++++++++++
 gtk/inspector/cssruleviewrow.c          |    2 +-
 9 files changed, 579 insertions(+), 95 deletions(-)
---
diff --git a/gtk/Makefile.am b/gtk/Makefile.am
index c68a0ae..699037e 100644
--- a/gtk/Makefile.am
+++ b/gtk/Makefile.am
@@ -425,6 +425,7 @@ gtk_private_h_sources =             \
        gtkcsskeyframeruleprivate.h     \
        gtkcsskeyframesprivate.h        \
        gtkcsskeyframesruleprivate.h    \
+       gtkcsslonghanddeclarationprivate.h      \
        gtkcsslookupprivate.h   \
        gtkcssmatcherprivate.h  \
        gtkcssnodeprivate.h             \
@@ -445,6 +446,7 @@ gtk_private_h_sources =             \
        gtkcssselectorprivate.h \
        gtkcssshadowsvalueprivate.h     \
        gtkcssshadowvalueprivate.h      \
+       gtkcssshorthanddeclarationprivate.h     \
        gtkcssshorthandpropertyprivate.h \
        gtkcssstaticstyleprivate.h      \
        gtkcssstringvalueprivate.h      \
@@ -706,6 +708,7 @@ gtk_base_c_sources =                \
        gtkcsskeyframerule.c    \
        gtkcsskeyframes.c       \
        gtkcsskeyframesrule.c   \
+       gtkcsslonghanddeclaration.c \
        gtkcsslookup.c          \
        gtkcssmatcher.c         \
        gtkcssnode.c            \
@@ -725,18 +728,19 @@ gtk_base_c_sources =              \
        gtkcsssection.c         \
        gtkcssselector.c        \
        gtkcssstringvalue.c     \
-       gtkcssstyle.c           \
-       gtkcssstylechange.c     \
-       gtkcssstyledeclaration.c \
-       gtkcssstylerule.c       \
        gtkcssshadowsvalue.c    \
        gtkcssshadowvalue.c     \
+       gtkcssshorthanddeclaration.c \
        gtkcssshorthandproperty.c \
        gtkcssshorthandpropertyimpl.c \
        gtkcssstaticstyle.c     \
+       gtkcssstyle.c           \
+       gtkcssstylechange.c     \
+       gtkcssstyledeclaration.c \
        gtkcssstylefuncs.c      \
        gtkcssstyleproperty.c   \
        gtkcssstylepropertyimpl.c \
+       gtkcssstylerule.c       \
        gtkcssstylesheet.c      \
        gtkcsstokenizer.c       \
        gtkcsstokensource.c     \
diff --git a/gtk/gtkcssdeclaration.c b/gtk/gtkcssdeclaration.c
index 0782cfa..dd83827 100644
--- a/gtk/gtkcssdeclaration.c
+++ b/gtk/gtkcssdeclaration.c
@@ -21,35 +21,20 @@
 
 #include "gtkcssdeclarationprivate.h"
 
+#include "gtkcsslonghanddeclarationprivate.h"
+#include "gtkcssshorthanddeclarationprivate.h"
 #include "gtkstylepropertyprivate.h"
 
 typedef struct _GtkCssDeclarationPrivate GtkCssDeclarationPrivate;
 struct _GtkCssDeclarationPrivate {
   GtkCssStyleDeclaration *style;
-  GtkStyleProperty *prop;
-  GtkCssValue *value;
 };
 
-G_DEFINE_TYPE_WITH_PRIVATE (GtkCssDeclaration, gtk_css_declaration, G_TYPE_OBJECT)
-
-static void
-gtk_css_declaration_finalize (GObject *object)
-{
-  GtkCssDeclaration *declaration = GTK_CSS_DECLARATION (object);
-  GtkCssDeclarationPrivate *priv = gtk_css_declaration_get_instance_private (declaration);
-
-  if (priv->value)
-    _gtk_css_value_unref (priv->value);
-
-  G_OBJECT_CLASS (gtk_css_declaration_parent_class)->finalize (object);
-}
+G_DEFINE_ABSTRACT_TYPE_WITH_PRIVATE (GtkCssDeclaration, gtk_css_declaration, G_TYPE_OBJECT)
 
 static void
 gtk_css_declaration_class_init (GtkCssDeclarationClass *klass)
 {
-  GObjectClass *object_class = G_OBJECT_CLASS (klass);
-
-  object_class->finalize = gtk_css_declaration_finalize;
 }
 
 static void
@@ -61,64 +46,34 @@ GtkCssDeclaration *
 gtk_css_declaration_new_parse (GtkCssStyleDeclaration *style,
                                GtkCssTokenSource      *source)
 {
-  GtkCssDeclarationPrivate *priv;
   const GtkCssToken *token;
-  GtkCssDeclaration *decl;
+  GtkStyleProperty *prop;
   char *name;
 
-  decl = g_object_new (GTK_TYPE_CSS_DECLARATION, NULL);
-  priv = gtk_css_declaration_get_instance_private (decl);
-
-  gtk_css_token_source_set_consumer (source, G_OBJECT (decl));
-
-  priv->style = style;
   token = gtk_css_token_source_get_token (source);
   if (!gtk_css_token_is (token, GTK_CSS_TOKEN_IDENT))
     {
       gtk_css_token_source_error (source, "Expected a property name");
       gtk_css_token_source_consume_all (source);
-      g_object_unref (decl);
       return NULL;
     }
   name = g_utf8_strdown (token->string.string, -1);
-  priv->prop = _gtk_style_property_lookup (name);
-  if (priv->prop == NULL)
-    {
-      gtk_css_token_source_unknown (source, "Unknown property name '%s'", token->string.string);
-      gtk_css_token_source_consume_all (source);
-      g_object_unref (decl);
-      g_free (name);
-      return NULL;
-    }
-  else if (!g_str_equal (name, _gtk_style_property_get_name (priv->prop)))
-    gtk_css_token_source_deprecated (source,
-                                     "The '%s' property has been renamed to '%s'",
-                                     name, _gtk_style_property_get_name (priv->prop));
-  gtk_css_token_source_consume_token (source);
+  prop = _gtk_style_property_lookup (name);
   g_free (name);
-
-  token = gtk_css_token_source_get_token (source);
-  if (!gtk_css_token_is (token, GTK_CSS_TOKEN_COLON))
+  if (GTK_IS_CSS_STYLE_PROPERTY (prop))
+    return gtk_css_longhand_declaration_new_parse (style, source);
+  else if (GTK_IS_CSS_SHORTHAND_PROPERTY (prop))
+    return gtk_css_shorthand_declaration_new_parse (style, source);
+  else
     {
-      gtk_css_token_source_error (source, "No colon following property name");
+      gtk_css_token_source_error (source, "Property name does not define a valid property");
       gtk_css_token_source_consume_all (source);
-      g_object_unref (decl);
       return NULL;
     }
-  gtk_css_token_source_consume_token (source);
-   
-  priv->value = gtk_style_property_token_parse (priv->prop, source);
-  if (priv->value == NULL)
-    {
-      g_object_unref (decl);
-      return NULL;
-    }
-
-  return decl;
 }
 
-const char *
-gtk_css_declaration_get_name (GtkCssDeclaration *decl)
+GtkCssStyleDeclaration *
+gtk_css_declaration_get_style (GtkCssDeclaration *decl)
 {
   GtkCssDeclarationPrivate *priv;
 
@@ -126,18 +81,36 @@ gtk_css_declaration_get_name (GtkCssDeclaration *decl)
 
   priv = gtk_css_declaration_get_instance_private (decl);
 
-  return _gtk_style_property_get_name (priv->prop);
+  return priv->style;
 }
 
-GtkCssValue *
-gtk_css_declaration_get_value (GtkCssDeclaration *decl)
+const char *
+gtk_css_declaration_get_name (GtkCssDeclaration *decl)
 {
-  GtkCssDeclarationPrivate *priv;
-
   g_return_val_if_fail (GTK_IS_CSS_DECLARATION (decl), NULL);
 
-  priv = gtk_css_declaration_get_instance_private (decl);
+  return GTK_CSS_DECLARATION_GET_CLASS (decl)->get_name (decl);
+}
+
+void
+gtk_css_declaration_print_value (GtkCssDeclaration *decl,
+                                 GString           *string)
+{
+  g_return_if_fail (GTK_IS_CSS_DECLARATION (decl));
+  g_return_if_fail (string != NULL);
 
-  return priv->value;
+  return GTK_CSS_DECLARATION_GET_CLASS (decl)->print_value (decl, string);
 }
 
+char *
+gtk_css_declaration_get_value_string (GtkCssDeclaration *decl)
+{
+  GString *string;
+
+  g_return_val_if_fail (GTK_IS_CSS_DECLARATION (decl), NULL);
+
+  string = g_string_new (NULL);
+  gtk_css_declaration_print_value (decl, string);
+
+  return g_string_free (string, FALSE);
+}
diff --git a/gtk/gtkcssdeclarationprivate.h b/gtk/gtkcssdeclarationprivate.h
index ffb6c25..f41b9b4 100644
--- a/gtk/gtkcssdeclarationprivate.h
+++ b/gtk/gtkcssdeclarationprivate.h
@@ -44,6 +44,10 @@ struct _GtkCssDeclaration
 struct _GtkCssDeclarationClass
 {
   GObjectClass parent_class;
+
+  const char *          (* get_name)                            (GtkCssDeclaration      *decl);
+  void                  (* print_value)                         (GtkCssDeclaration      *decl,
+                                                                 GString                *string);
 };
 
 GType                   gtk_css_declaration_get_type            (void) G_GNUC_CONST;
@@ -52,7 +56,11 @@ GtkCssDeclaration *     gtk_css_declaration_new_parse           (GtkCssStyleDecl
                                                                  GtkCssTokenSource      *source);
 
 const char *            gtk_css_declaration_get_name            (GtkCssDeclaration      *decl);
-GtkCssValue *           gtk_css_declaration_get_value           (GtkCssDeclaration      *decl);
+GtkCssStyleDeclaration *gtk_css_declaration_get_style           (GtkCssDeclaration      *decl);
+
+void                    gtk_css_declaration_print_value         (GtkCssDeclaration      *decl,
+                                                                 GString                *string);
+char *                  gtk_css_declaration_get_value_string    (GtkCssDeclaration      *decl);
 
 
 G_END_DECLS
diff --git a/gtk/gtkcsskeyframes.c b/gtk/gtkcsskeyframes.c
index c1ea28d..2c2a55b 100644
--- a/gtk/gtkcsskeyframes.c
+++ b/gtk/gtkcsskeyframes.c
@@ -20,10 +20,10 @@
 #include "gtkcsskeyframesprivate.h"
 
 #include "gtkcssarrayvalueprivate.h"
-#include "gtkcssdeclarationprivate.h"
 #include "gtkcsskeyframeruleprivate.h"
+#include "gtkcsslonghanddeclarationprivate.h"
+#include "gtkcssshorthanddeclarationprivate.h"
 #include "gtkcssshorthandpropertyprivate.h"
-#include "gtkcssstylepropertyprivate.h"
 #include "gtkstylepropertyprivate.h"
 
 #include <stdlib.h>
@@ -405,34 +405,27 @@ gtk_css_keyframes_new_from_rule (GtkCssKeyframesRule *rule)
           for (k = 0; k < gtk_css_style_declaration_get_length (style); k++)
             {
               GtkCssDeclaration *decl = gtk_css_style_declaration_get_declaration (style, k);
-              GtkStyleProperty *property;
-              GtkCssValue *value;
 
-              property = _gtk_style_property_lookup (gtk_css_declaration_get_name (decl));
-              if (property == NULL)
-                continue;
-
-              value = gtk_css_declaration_get_value (decl);
-              if (GTK_IS_CSS_SHORTHAND_PROPERTY (property))
+              if (GTK_IS_CSS_LONGHAND_DECLARATION (decl))
                 {
-                  GtkCssShorthandProperty *shorthand = GTK_CSS_SHORTHAND_PROPERTY (property);
+                  GtkCssLonghandDeclaration *longhand = GTK_CSS_LONGHAND_DECLARATION (decl);
+                  keyframes_set_value (keyframes,
+                                       offset_idx,
+                                       gtk_css_longhand_declaration_get_property (longhand),
+                                       _gtk_css_value_ref (gtk_css_longhand_declaration_get_value 
(longhand)));
+                }
+              else if (GTK_IS_CSS_SHORTHAND_DECLARATION (decl))
+                {
+                  GtkCssShorthandDeclaration *shorthand = GTK_CSS_SHORTHAND_DECLARATION (decl);
 
-                  for (l = 0; l < _gtk_css_shorthand_property_get_n_subproperties (shorthand); l++)
+                  for (l = 0; l < gtk_css_shorthand_declaration_get_length (shorthand); l++)
                     {
-                      GtkCssStyleProperty *child = _gtk_css_shorthand_property_get_subproperty (shorthand, 
l);
-                      GtkCssValue *sub = _gtk_css_array_value_get_nth (value, l);
-
-                      keyframes_set_value (keyframes, offset_idx, child, _gtk_css_value_ref (sub));
+                      keyframes_set_value (keyframes,
+                                           offset_idx,
+                                           gtk_css_shorthand_declaration_get_subproperty (shorthand, l),
+                                           _gtk_css_value_ref (gtk_css_shorthand_declaration_get_value 
(shorthand, l)));
                     }
                 }
-              else if (GTK_IS_CSS_STYLE_PROPERTY (property))
-                {
-                  keyframes_set_value (keyframes, offset_idx, GTK_CSS_STYLE_PROPERTY (property), 
_gtk_css_value_ref (value));
-                }
-              else
-                {
-                  g_assert_not_reached ();
-                }
             }
         }
     }
diff --git a/gtk/gtkcsslonghanddeclaration.c b/gtk/gtkcsslonghanddeclaration.c
new file mode 100644
index 0000000..086b06e
--- /dev/null
+++ b/gtk/gtkcsslonghanddeclaration.c
@@ -0,0 +1,177 @@
+/*
+ * Copyright © 2016 Red Hat Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * Authors: Benjamin Otte <otte gnome org>
+ */
+
+#include "config.h"
+
+#include "gtkcsslonghanddeclarationprivate.h"
+
+#include "gtkcssstylepropertyprivate.h"
+
+typedef struct _GtkCssLonghandDeclarationPrivate GtkCssLonghandDeclarationPrivate;
+struct _GtkCssLonghandDeclarationPrivate {
+  GtkCssStyleProperty *prop;
+  GtkCssValue *value;
+};
+
+G_DEFINE_TYPE_WITH_PRIVATE (GtkCssLonghandDeclaration, gtk_css_longhand_declaration, 
GTK_TYPE_CSS_DECLARATION)
+
+static void
+gtk_css_longhand_declaration_finalize (GObject *object)
+{
+  GtkCssLonghandDeclaration *longhand_declaration = GTK_CSS_LONGHAND_DECLARATION (object);
+  GtkCssLonghandDeclarationPrivate *priv = gtk_css_longhand_declaration_get_instance_private 
(longhand_declaration);
+
+  if (priv->value)
+    _gtk_css_value_unref (priv->value);
+
+  G_OBJECT_CLASS (gtk_css_longhand_declaration_parent_class)->finalize (object);
+}
+
+static const char *
+gtk_css_longhand_declaration_get_name (GtkCssDeclaration *decl)
+{
+  GtkCssLonghandDeclaration *longhand_declaration = GTK_CSS_LONGHAND_DECLARATION (decl);
+  GtkCssLonghandDeclarationPrivate *priv = gtk_css_longhand_declaration_get_instance_private 
(longhand_declaration);
+
+  return _gtk_style_property_get_name (GTK_STYLE_PROPERTY (priv->prop));
+}
+
+static void
+gtk_css_longhand_declaration_print_value (GtkCssDeclaration *decl,
+                                          GString           *string)
+{
+  GtkCssLonghandDeclaration *longhand_declaration = GTK_CSS_LONGHAND_DECLARATION (decl);
+  GtkCssLonghandDeclarationPrivate *priv = gtk_css_longhand_declaration_get_instance_private 
(longhand_declaration);
+
+  _gtk_css_value_print (priv->value, string);
+}
+
+static void
+gtk_css_longhand_declaration_class_init (GtkCssLonghandDeclarationClass *klass)
+{
+  GObjectClass *object_class = G_OBJECT_CLASS (klass);
+  GtkCssDeclarationClass *decl_class = GTK_CSS_DECLARATION_CLASS (klass);
+
+  object_class->finalize = gtk_css_longhand_declaration_finalize;
+
+  decl_class->get_name = gtk_css_longhand_declaration_get_name;
+  decl_class->print_value = gtk_css_longhand_declaration_print_value;
+}
+
+static void
+gtk_css_longhand_declaration_init (GtkCssLonghandDeclaration *longhand_declaration)
+{
+}
+
+GtkCssDeclaration *
+gtk_css_longhand_declaration_new_parse (GtkCssStyleDeclaration *style,
+                                         GtkCssTokenSource      *source)
+{
+  GtkCssLonghandDeclarationPrivate *priv;
+  const GtkCssToken *token;
+  GtkCssLonghandDeclaration *decl;
+  char *name;
+
+  decl = g_object_new (GTK_TYPE_CSS_LONGHAND_DECLARATION,
+                       NULL);
+  priv = gtk_css_longhand_declaration_get_instance_private (decl);
+
+  gtk_css_token_source_set_consumer (source, G_OBJECT (decl));
+
+  token = gtk_css_token_source_get_token (source);
+  if (!gtk_css_token_is (token, GTK_CSS_TOKEN_IDENT))
+    {
+      gtk_css_token_source_error (source, "Expected a property name");
+      gtk_css_token_source_consume_all (source);
+      g_object_unref (decl);
+      return NULL;
+    }
+  name = g_utf8_strdown (token->string.string, -1);
+  priv->prop = (GtkCssStyleProperty *) _gtk_style_property_lookup (name);
+  if (!GTK_IS_CSS_STYLE_PROPERTY (priv->prop))
+    {
+      gtk_css_token_source_unknown (source, "Property name '%s' is not a CSS property", 
token->string.string);
+      gtk_css_token_source_consume_all (source);
+      g_object_unref (decl);
+      g_free (name);
+      return NULL;
+    }
+  else if (!g_str_equal (name, _gtk_style_property_get_name (GTK_STYLE_PROPERTY (priv->prop))))
+    gtk_css_token_source_deprecated (source,
+                                     "The '%s' property has been renamed to '%s'",
+                                     name, _gtk_style_property_get_name (GTK_STYLE_PROPERTY (priv->prop)));
+  gtk_css_token_source_consume_token (source);
+  g_free (name);
+
+  token = gtk_css_token_source_get_token (source);
+  if (!gtk_css_token_is (token, GTK_CSS_TOKEN_COLON))
+    {
+      gtk_css_token_source_error (source, "No colon following property name");
+      gtk_css_token_source_consume_all (source);
+      g_object_unref (decl);
+      return NULL;
+    }
+  gtk_css_token_source_consume_token (source);
+   
+  priv->value = gtk_style_property_token_parse (GTK_STYLE_PROPERTY (priv->prop), source);
+  if (priv->value == NULL)
+    {
+      g_object_unref (decl);
+      return NULL;
+    }
+
+  return GTK_CSS_DECLARATION (decl);
+}
+
+guint
+gtk_css_longhand_declaration_get_id (GtkCssLonghandDeclaration *decl)
+{
+  GtkCssLonghandDeclarationPrivate *priv;
+
+  g_return_val_if_fail (GTK_IS_CSS_LONGHAND_DECLARATION (decl), 0);
+
+  priv = gtk_css_longhand_declaration_get_instance_private (decl);
+
+  return _gtk_css_style_property_get_id (priv->prop);
+}
+
+GtkCssStyleProperty *
+gtk_css_longhand_declaration_get_property (GtkCssLonghandDeclaration *decl)
+{
+  GtkCssLonghandDeclarationPrivate *priv;
+
+  g_return_val_if_fail (GTK_IS_CSS_LONGHAND_DECLARATION (decl), 0);
+
+  priv = gtk_css_longhand_declaration_get_instance_private (decl);
+
+  return priv->prop;
+}
+
+GtkCssValue *
+gtk_css_longhand_declaration_get_value (GtkCssLonghandDeclaration *decl)
+{
+  GtkCssLonghandDeclarationPrivate *priv;
+
+  g_return_val_if_fail (GTK_IS_CSS_LONGHAND_DECLARATION (decl), NULL);
+
+  priv = gtk_css_longhand_declaration_get_instance_private (decl);
+
+  return priv->value;
+}
+
diff --git a/gtk/gtkcsslonghanddeclarationprivate.h b/gtk/gtkcsslonghanddeclarationprivate.h
new file mode 100644
index 0000000..c383c68
--- /dev/null
+++ b/gtk/gtkcsslonghanddeclarationprivate.h
@@ -0,0 +1,62 @@
+/*
+ * Copyright © 2016 Red Hat Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * Authors: Benjamin Otte <otte gnome org>
+ */
+
+#ifndef __GTK_CSS_LONGHAND_DECLARATION_PRIVATE_H__
+#define __GTK_CSS_LONGHAND_DECLARATION_PRIVATE_H__
+
+#include "gtk/gtkcssdeclarationprivate.h"
+
+#include "gtk/gtkcssstylepropertyprivate.h"
+#include "gtk/gtkcssvalueprivate.h"
+
+G_BEGIN_DECLS
+
+#define GTK_TYPE_CSS_LONGHAND_DECLARATION           (gtk_css_longhand_declaration_get_type ())
+#define GTK_CSS_LONGHAND_DECLARATION(obj)           (G_TYPE_CHECK_INSTANCE_CAST (obj, 
GTK_TYPE_CSS_LONGHAND_DECLARATION, GtkCssLonghandDeclaration))
+#define GTK_CSS_LONGHAND_DECLARATION_CLASS(cls)     (G_TYPE_CHECK_CLASS_CAST (cls, 
GTK_TYPE_CSS_LONGHAND_DECLARATION, GtkCssLonghandDeclarationClass))
+#define GTK_IS_CSS_LONGHAND_DECLARATION(obj)        (G_TYPE_CHECK_INSTANCE_TYPE (obj, 
GTK_TYPE_CSS_LONGHAND_DECLARATION))
+#define GTK_IS_CSS_LONGHAND_DECLARATION_CLASS(obj)  (G_TYPE_CHECK_CLASS_TYPE (obj, 
GTK_TYPE_CSS_LONGHAND_DECLARATION))
+#define GTK_CSS_LONGHAND_DECLARATION_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), 
GTK_TYPE_CSS_LONGHAND_DECLARATION, GtkCssLonghandDeclarationClass))
+
+typedef struct _GtkCssLonghandDeclaration           GtkCssLonghandDeclaration;
+typedef struct _GtkCssLonghandDeclarationClass      GtkCssLonghandDeclarationClass;
+
+struct _GtkCssLonghandDeclaration
+{
+  GtkCssDeclaration parent;
+};
+
+struct _GtkCssLonghandDeclarationClass
+{
+  GtkCssDeclarationClass parent_class;
+};
+
+GType                   gtk_css_longhand_declaration_get_type           (void) G_GNUC_CONST;
+  
+GtkCssDeclaration *     gtk_css_longhand_declaration_new_parse          (GtkCssStyleDeclaration         
*style,
+                                                                         GtkCssTokenSource              
*source);
+
+guint                   gtk_css_longhand_declaration_get_id             (GtkCssLonghandDeclaration      
*decl);
+GtkCssStyleProperty *   gtk_css_longhand_declaration_get_property       (GtkCssLonghandDeclaration      
*decl);
+GtkCssValue *           gtk_css_longhand_declaration_get_value          (GtkCssLonghandDeclaration      
*decl);
+
+
+G_END_DECLS
+
+#endif /* __GTK_CSS_LONGHAND_DECLARATION_PRIVATE_H__ */
diff --git a/gtk/gtkcssshorthanddeclaration.c b/gtk/gtkcssshorthanddeclaration.c
new file mode 100644
index 0000000..5b9b1a3
--- /dev/null
+++ b/gtk/gtkcssshorthanddeclaration.c
@@ -0,0 +1,203 @@
+/*
+ * Copyright © 2016 Red Hat Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * Authors: Benjamin Otte <otte gnome org>
+ */
+
+#include "config.h"
+
+#include "gtkcssshorthanddeclarationprivate.h"
+
+#include "gtkcssarrayvalueprivate.h"
+#include "gtkcssshorthandpropertyprivate.h"
+
+typedef struct _GtkCssShorthandDeclarationPrivate GtkCssShorthandDeclarationPrivate;
+struct _GtkCssShorthandDeclarationPrivate {
+  GtkCssShorthandProperty *prop;
+  GtkCssValue **values;
+};
+
+G_DEFINE_TYPE_WITH_PRIVATE (GtkCssShorthandDeclaration, gtk_css_shorthand_declaration, 
GTK_TYPE_CSS_DECLARATION)
+
+static void
+gtk_css_shorthand_declaration_finalize (GObject *object)
+{
+  GtkCssShorthandDeclaration *shorthand = GTK_CSS_SHORTHAND_DECLARATION (object);
+  GtkCssShorthandDeclarationPrivate *priv = gtk_css_shorthand_declaration_get_instance_private (shorthand);
+  guint i;
+
+  if (priv->values)
+    {
+      for (i = 0; i < gtk_css_shorthand_declaration_get_length (shorthand); i++)
+        {
+          _gtk_css_value_unref (priv->values[i]);
+        }
+      g_free (priv->values);
+    }
+
+  G_OBJECT_CLASS (gtk_css_shorthand_declaration_parent_class)->finalize (object);
+}
+
+static const char *
+gtk_css_shorthand_declaration_get_name (GtkCssDeclaration *decl)
+{
+  GtkCssShorthandDeclaration *shorthand_declaration = GTK_CSS_SHORTHAND_DECLARATION (decl);
+  GtkCssShorthandDeclarationPrivate *priv = gtk_css_shorthand_declaration_get_instance_private 
(shorthand_declaration);
+
+  return _gtk_style_property_get_name (GTK_STYLE_PROPERTY (priv->prop));
+}
+
+static void
+gtk_css_shorthand_declaration_print_value (GtkCssDeclaration *decl,
+                                           GString           *string)
+{
+  GtkCssShorthandDeclaration *shorthand = GTK_CSS_SHORTHAND_DECLARATION (decl);
+  GtkCssShorthandDeclarationPrivate *priv = gtk_css_shorthand_declaration_get_instance_private (shorthand);
+  guint i;
+
+  /* XXX */
+  for (i = 0; i < gtk_css_shorthand_declaration_get_length (shorthand); i++)
+    {
+      if (i > 0)
+        g_string_append (string, ", ");
+      _gtk_css_value_print (priv->values[i], string);
+    }
+}
+
+static void
+gtk_css_shorthand_declaration_class_init (GtkCssShorthandDeclarationClass *klass)
+{
+  GObjectClass *object_class = G_OBJECT_CLASS (klass);
+  GtkCssDeclarationClass *decl_class = GTK_CSS_DECLARATION_CLASS (klass);
+
+  object_class->finalize = gtk_css_shorthand_declaration_finalize;
+
+  decl_class->get_name = gtk_css_shorthand_declaration_get_name;
+  decl_class->print_value = gtk_css_shorthand_declaration_print_value;
+}
+
+static void
+gtk_css_shorthand_declaration_init (GtkCssShorthandDeclaration *shorthand_declaration)
+{
+}
+
+GtkCssDeclaration *
+gtk_css_shorthand_declaration_new_parse (GtkCssStyleDeclaration *style,
+                                         GtkCssTokenSource      *source)
+{
+  GtkCssShorthandDeclarationPrivate *priv;
+  const GtkCssToken *token;
+  GtkCssShorthandDeclaration *decl;
+  GtkCssValue *array;
+  guint i;
+  char *name;
+
+  decl = g_object_new (GTK_TYPE_CSS_SHORTHAND_DECLARATION, NULL);
+  priv = gtk_css_shorthand_declaration_get_instance_private (decl);
+
+  gtk_css_token_source_set_consumer (source, G_OBJECT (decl));
+
+  token = gtk_css_token_source_get_token (source);
+  if (!gtk_css_token_is (token, GTK_CSS_TOKEN_IDENT))
+    {
+      gtk_css_token_source_error (source, "Expected a property name");
+      gtk_css_token_source_consume_all (source);
+      g_object_unref (decl);
+      return NULL;
+    }
+  name = g_utf8_strdown (token->string.string, -1);
+  priv->prop = (GtkCssShorthandProperty *) _gtk_style_property_lookup (name);
+  if (!GTK_IS_CSS_SHORTHAND_PROPERTY (priv->prop))
+    {
+      gtk_css_token_source_unknown (source, "Property name '%s' is not a shorthand property", 
token->string.string);
+      gtk_css_token_source_consume_all (source);
+      g_object_unref (decl);
+      g_free (name);
+      return NULL;
+    }
+  else if (!g_str_equal (name, _gtk_style_property_get_name (GTK_STYLE_PROPERTY (priv->prop))))
+    gtk_css_token_source_deprecated (source,
+                                     "The '%s' property has been renamed to '%s'",
+                                     name, _gtk_style_property_get_name (GTK_STYLE_PROPERTY (priv->prop)));
+  gtk_css_token_source_consume_token (source);
+  g_free (name);
+
+  token = gtk_css_token_source_get_token (source);
+  if (!gtk_css_token_is (token, GTK_CSS_TOKEN_COLON))
+    {
+      gtk_css_token_source_error (source, "No colon following property name");
+      gtk_css_token_source_consume_all (source);
+      g_object_unref (decl);
+      return NULL;
+    }
+  gtk_css_token_source_consume_token (source);
+   
+  array = gtk_style_property_token_parse (GTK_STYLE_PROPERTY (priv->prop), source);
+  if (array == NULL)
+    {
+      g_object_unref (decl);
+      return NULL;
+    }
+  priv->values = g_new (GtkCssValue *, gtk_css_shorthand_declaration_get_length (decl));
+  for (i = 0; i < gtk_css_shorthand_declaration_get_length (decl); i++)
+    {
+      priv->values[i] = _gtk_css_value_ref (_gtk_css_array_value_get_nth (array, i));
+    }
+  _gtk_css_value_unref (array);
+
+  return GTK_CSS_DECLARATION (decl);
+}
+
+guint
+gtk_css_shorthand_declaration_get_length (GtkCssShorthandDeclaration *decl)
+{
+  GtkCssShorthandDeclarationPrivate *priv;
+
+  g_return_val_if_fail (GTK_IS_CSS_SHORTHAND_DECLARATION (decl), 0);
+
+  priv = gtk_css_shorthand_declaration_get_instance_private (decl);
+
+  return _gtk_css_shorthand_property_get_n_subproperties (priv->prop);
+}
+
+GtkCssStyleProperty *
+gtk_css_shorthand_declaration_get_subproperty (GtkCssShorthandDeclaration *decl,
+                                               guint                       id)
+{
+  GtkCssShorthandDeclarationPrivate *priv;
+
+  g_return_val_if_fail (GTK_IS_CSS_SHORTHAND_DECLARATION (decl), NULL);
+  g_return_val_if_fail (id < gtk_css_shorthand_declaration_get_length (decl), NULL);
+
+  priv = gtk_css_shorthand_declaration_get_instance_private (decl);
+
+  return _gtk_css_shorthand_property_get_subproperty (priv->prop, id);
+}
+
+GtkCssValue *
+gtk_css_shorthand_declaration_get_value (GtkCssShorthandDeclaration *decl,
+                                         guint                       id)
+{
+  GtkCssShorthandDeclarationPrivate *priv;
+
+  g_return_val_if_fail (GTK_IS_CSS_SHORTHAND_DECLARATION (decl), NULL);
+  g_return_val_if_fail (id < gtk_css_shorthand_declaration_get_length (decl), NULL);
+
+  priv = gtk_css_shorthand_declaration_get_instance_private (decl);
+
+  return priv->values[id];
+}
+
diff --git a/gtk/gtkcssshorthanddeclarationprivate.h b/gtk/gtkcssshorthanddeclarationprivate.h
new file mode 100644
index 0000000..48269bb
--- /dev/null
+++ b/gtk/gtkcssshorthanddeclarationprivate.h
@@ -0,0 +1,64 @@
+/*
+ * Copyright © 2016 Red Hat Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * Authors: Benjamin Otte <otte gnome org>
+ */
+
+#ifndef __GTK_CSS_SHORTHAND_DECLARATION_PRIVATE_H__
+#define __GTK_CSS_SHORTHAND_DECLARATION_PRIVATE_H__
+
+#include "gtk/gtkcssdeclarationprivate.h"
+
+#include "gtk/gtkcssshorthandpropertyprivate.h"
+#include "gtk/gtkcssvalueprivate.h"
+
+G_BEGIN_DECLS
+
+#define GTK_TYPE_CSS_SHORTHAND_DECLARATION           (gtk_css_shorthand_declaration_get_type ())
+#define GTK_CSS_SHORTHAND_DECLARATION(obj)           (G_TYPE_CHECK_INSTANCE_CAST (obj, 
GTK_TYPE_CSS_SHORTHAND_DECLARATION, GtkCssShorthandDeclaration))
+#define GTK_CSS_SHORTHAND_DECLARATION_CLASS(cls)     (G_TYPE_CHECK_CLASS_CAST (cls, 
GTK_TYPE_CSS_SHORTHAND_DECLARATION, GtkCssShorthandDeclarationClass))
+#define GTK_IS_CSS_SHORTHAND_DECLARATION(obj)        (G_TYPE_CHECK_INSTANCE_TYPE (obj, 
GTK_TYPE_CSS_SHORTHAND_DECLARATION))
+#define GTK_IS_CSS_SHORTHAND_DECLARATION_CLASS(obj)  (G_TYPE_CHECK_CLASS_TYPE (obj, 
GTK_TYPE_CSS_SHORTHAND_DECLARATION))
+#define GTK_CSS_SHORTHAND_DECLARATION_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), 
GTK_TYPE_CSS_SHORTHAND_DECLARATION, GtkCssShorthandDeclarationClass))
+
+typedef struct _GtkCssShorthandDeclaration           GtkCssShorthandDeclaration;
+typedef struct _GtkCssShorthandDeclarationClass      GtkCssShorthandDeclarationClass;
+
+struct _GtkCssShorthandDeclaration
+{
+  GtkCssDeclaration parent;
+};
+
+struct _GtkCssShorthandDeclarationClass
+{
+  GtkCssDeclarationClass parent_class;
+};
+
+GType                   gtk_css_shorthand_declaration_get_type          (void) G_GNUC_CONST;
+  
+GtkCssDeclaration *     gtk_css_shorthand_declaration_new_parse         (GtkCssStyleDeclaration         
*style,
+                                                                         GtkCssTokenSource              
*source);
+
+guint                   gtk_css_shorthand_declaration_get_length        (GtkCssShorthandDeclaration     
*decl);
+GtkCssStyleProperty *   gtk_css_shorthand_declaration_get_subproperty   (GtkCssShorthandDeclaration     
*decl,
+                                                                         guint                           id);
+GtkCssValue *           gtk_css_shorthand_declaration_get_value         (GtkCssShorthandDeclaration     
*decl,
+                                                                         guint                           id);
+
+
+G_END_DECLS
+
+#endif /* __GTK_CSS_SHORTHAND_DECLARATION_PRIVATE_H__ */
diff --git a/gtk/inspector/cssruleviewrow.c b/gtk/inspector/cssruleviewrow.c
index b143c24..4fcfe9d 100644
--- a/gtk/inspector/cssruleviewrow.c
+++ b/gtk/inspector/cssruleviewrow.c
@@ -127,7 +127,7 @@ update_style_label (GtkInspectorCssRuleViewRow *row)
         g_string_append (string, "\n");
       g_string_append (string, gtk_css_declaration_get_name (decl));
       g_string_append (string, ": ");
-      _gtk_css_value_print (gtk_css_declaration_get_value (decl), string);
+      gtk_css_declaration_print_value (decl, string);
       g_string_append (string, ";");
     }
   gtk_label_set_text (GTK_LABEL (priv->style_label), string->str);


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