[gtk+/wip/otte/tokenizer: 57/78] css: Parse widget styles with token parser



commit 9d07be0238bab6d40ed453bf303b5e3959b875c8
Author: Benjamin Otte <otte redhat com>
Date:   Sat Mar 26 06:17:51 2016 +0100

    css: Parse widget styles with token parser

 gtk/Makefile.am                           |    2 +
 gtk/gtkcssdeclaration.c                   |    7 +-
 gtk/gtkcsswidgetstyledeclaration.c        |  197 +++++++++++++++++++++++++++++
 gtk/gtkcsswidgetstyledeclarationprivate.h |   57 +++++++++
 4 files changed, 262 insertions(+), 1 deletions(-)
---
diff --git a/gtk/Makefile.am b/gtk/Makefile.am
index 699037e..18fed3a 100644
--- a/gtk/Makefile.am
+++ b/gtk/Makefile.am
@@ -467,6 +467,7 @@ gtk_private_h_sources =             \
        gtkcssvalueprivate.h    \
        gtkcsswin32sizevalueprivate.h   \
        gtkcsswidgetnodeprivate.h       \
+       gtkcsswidgetstyledeclarationprivate.h \
        gtkcustompaperunixdialog.h \
        gtkdialogprivate.h      \
        gtkdndprivate.h         \
@@ -752,6 +753,7 @@ gtk_base_c_sources =                \
        gtkcsstypes.c           \
        gtkcssvalue.c           \
        gtkcsswidgetnode.c      \
+       gtkcsswidgetstyledeclaration.c \
         gtkcsswin32sizevalue.c  \
        gtkdialog.c             \
        gtkdragsource.c         \
diff --git a/gtk/gtkcssdeclaration.c b/gtk/gtkcssdeclaration.c
index 1d1d09f..aed4a30 100644
--- a/gtk/gtkcssdeclaration.c
+++ b/gtk/gtkcssdeclaration.c
@@ -23,6 +23,7 @@
 
 #include "gtkcsslonghanddeclarationprivate.h"
 #include "gtkcssshorthanddeclarationprivate.h"
+#include "gtkcsswidgetstyledeclarationprivate.h"
 #include "gtkstylepropertyprivate.h"
 #include "gtkintl.h"
 #include "gtkprivate.h"
@@ -139,9 +140,13 @@ gtk_css_declaration_new_parse (GtkCssStyleDeclaration *style,
     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 if (gtk_css_widget_style_declaration_accepts_name (token->string.string))
+    return gtk_css_widget_style_declaration_new_parse (style, source);
   else
     {
-      gtk_css_token_source_error (source, "Property name does not define a valid property");
+      gtk_css_token_source_unknown (source,
+                                    "Property name \"%s\" does not define a valid property",
+                                    token->string.string);
       gtk_css_token_source_consume_all (source);
       return NULL;
     }
diff --git a/gtk/gtkcsswidgetstyledeclaration.c b/gtk/gtkcsswidgetstyledeclaration.c
new file mode 100644
index 0000000..7b5e458
--- /dev/null
+++ b/gtk/gtkcsswidgetstyledeclaration.c
@@ -0,0 +1,197 @@
+/*
+ * 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 "gtkcsswidgetstyledeclarationprivate.h"
+
+#include "gtkwidget.h"
+
+#include <string.h>
+
+typedef struct _GtkCssWidgetStyleDeclarationPrivate GtkCssWidgetStyleDeclarationPrivate;
+struct _GtkCssWidgetStyleDeclarationPrivate {
+  char *name;
+  char *value;
+};
+
+G_DEFINE_TYPE_WITH_PRIVATE (GtkCssWidgetStyleDeclaration, gtk_css_widget_style_declaration, 
GTK_TYPE_CSS_DECLARATION)
+
+static void
+gtk_css_widget_style_declaration_finalize (GObject *object)
+{
+  GtkCssWidgetStyleDeclaration *widget_style = GTK_CSS_WIDGET_STYLE_DECLARATION (object);
+  GtkCssWidgetStyleDeclarationPrivate *priv = gtk_css_widget_style_declaration_get_instance_private 
(widget_style);
+
+  g_free (priv->name);
+  g_free (priv->value);
+
+  G_OBJECT_CLASS (gtk_css_widget_style_declaration_parent_class)->finalize (object);
+}
+
+static const char *
+gtk_css_widget_style_declaration_get_name (GtkCssDeclaration *decl)
+{
+  GtkCssWidgetStyleDeclaration *widget_style_declaration = GTK_CSS_WIDGET_STYLE_DECLARATION (decl);
+  GtkCssWidgetStyleDeclarationPrivate *priv = gtk_css_widget_style_declaration_get_instance_private 
(widget_style_declaration);
+
+  return priv->name;
+}
+
+static void
+gtk_css_widget_style_declaration_print_value (GtkCssDeclaration *decl,
+                                              GString           *string)
+{
+  GtkCssWidgetStyleDeclaration *widget_style = GTK_CSS_WIDGET_STYLE_DECLARATION (decl);
+  GtkCssWidgetStyleDeclarationPrivate *priv = gtk_css_widget_style_declaration_get_instance_private 
(widget_style);
+
+  g_string_append (string, priv->value);
+}
+
+static void
+gtk_css_widget_style_declaration_class_init (GtkCssWidgetStyleDeclarationClass *klass)
+{
+  GObjectClass *object_class = G_OBJECT_CLASS (klass);
+  GtkCssDeclarationClass *decl_class = GTK_CSS_DECLARATION_CLASS (klass);
+
+  object_class->finalize = gtk_css_widget_style_declaration_finalize;
+
+  decl_class->get_name = gtk_css_widget_style_declaration_get_name;
+  decl_class->print_value = gtk_css_widget_style_declaration_print_value;
+}
+
+static void
+gtk_css_widget_style_declaration_init (GtkCssWidgetStyleDeclaration *widget_style_declaration)
+{
+}
+
+gboolean
+gtk_css_widget_style_declaration_accepts_name (const char *name)
+{
+  g_return_val_if_fail (name != NULL, FALSE);
+
+  if (name[0] != '-')
+    return FALSE;
+
+  if (g_str_has_prefix (name, "-gtk-"))
+    return FALSE;
+
+  return TRUE;
+}
+
+static void
+warn_if_deprecated (GtkCssTokenSource *source,
+                    const gchar       *name)
+{
+  gchar *n = NULL;
+  gchar *p;
+  const gchar *type_name;
+  const gchar *property_name;
+  GType type;
+  GTypeClass *class = NULL;
+  GParamSpec *pspec;
+
+  n = g_strdup (name);
+
+  /* skip initial - */
+  type_name = n + 1;
+
+  p = strchr (type_name, '-');
+  if (!p)
+    goto out;
+
+  p[0] = '\0';
+  property_name = p + 1;
+
+  type = g_type_from_name (type_name);
+  if (type == G_TYPE_INVALID ||
+      !g_type_is_a (type, GTK_TYPE_WIDGET))
+    goto out;
+
+  class = g_type_class_ref (type);
+  pspec = gtk_widget_class_find_style_property (GTK_WIDGET_CLASS (class), property_name);
+  if (!pspec)
+    goto out;
+
+  if (!(pspec->flags & G_PARAM_DEPRECATED))
+    goto out;
+
+  gtk_css_token_source_deprecated (source,
+                                   "The style property %s:%s is deprecated and shouldn't be "
+                                   "used anymore. It will be removed in a future version",
+                                   g_type_name (pspec->owner_type), pspec->name);
+
+out:
+  g_free (n);
+  if (class)
+    g_type_class_unref (class);
+}
+
+GtkCssDeclaration *
+gtk_css_widget_style_declaration_new_parse (GtkCssStyleDeclaration *style,
+                                            GtkCssTokenSource      *source)
+{
+  GtkCssWidgetStyleDeclarationPrivate *priv;
+  const GtkCssToken *token;
+  GtkCssWidgetStyleDeclaration *decl;
+
+  decl = g_object_new (GTK_TYPE_CSS_WIDGET_STYLE_DECLARATION,
+                       "parent-style", style,
+                       NULL);
+  priv = gtk_css_widget_style_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;
+    }
+  if (!gtk_css_widget_style_declaration_accepts_name (token->string.string))
+    {
+      gtk_css_token_source_unknown (source, "Property name '%s' is not valid for a widget style property", 
token->string.string);
+      gtk_css_token_source_consume_all (source);
+      g_object_unref (decl);
+      return NULL;
+    }
+  
+  priv->name = g_strdup (token->string.string);
+  warn_if_deprecated (source, priv->name);
+  gtk_css_token_source_consume_token (source);
+
+  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);
+   
+  /* skip whitespace */
+  gtk_css_token_source_get_token (source);
+  priv->value = gtk_css_token_source_consume_to_string (source);
+
+  return GTK_CSS_DECLARATION (decl);
+}
+
diff --git a/gtk/gtkcsswidgetstyledeclarationprivate.h b/gtk/gtkcsswidgetstyledeclarationprivate.h
new file mode 100644
index 0000000..555232f
--- /dev/null
+++ b/gtk/gtkcsswidgetstyledeclarationprivate.h
@@ -0,0 +1,57 @@
+/*
+ * 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_WIDGET_STYLE_DECLARATION_PRIVATE_H__
+#define __GTK_CSS_WIDGET_STYLE_DECLARATION_PRIVATE_H__
+
+#include "gtk/gtkcssdeclarationprivate.h"
+
+G_BEGIN_DECLS
+
+#define GTK_TYPE_CSS_WIDGET_STYLE_DECLARATION           (gtk_css_widget_style_declaration_get_type ())
+#define GTK_CSS_WIDGET_STYLE_DECLARATION(obj)           (G_TYPE_CHECK_INSTANCE_CAST (obj, 
GTK_TYPE_CSS_WIDGET_STYLE_DECLARATION, GtkCssWidgetStyleDeclaration))
+#define GTK_CSS_WIDGET_STYLE_DECLARATION_CLASS(cls)     (G_TYPE_CHECK_CLASS_CAST (cls, 
GTK_TYPE_CSS_WIDGET_STYLE_DECLARATION, GtkCssWidgetStyleDeclarationClass))
+#define GTK_IS_CSS_WIDGET_STYLE_DECLARATION(obj)        (G_TYPE_CHECK_INSTANCE_TYPE (obj, 
GTK_TYPE_CSS_WIDGET_STYLE_DECLARATION))
+#define GTK_IS_CSS_WIDGET_STYLE_DECLARATION_CLASS(obj)  (G_TYPE_CHECK_CLASS_TYPE (obj, 
GTK_TYPE_CSS_WIDGET_STYLE_DECLARATION))
+#define GTK_CSS_WIDGET_STYLE_DECLARATION_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), 
GTK_TYPE_CSS_WIDGET_STYLE_DECLARATION, GtkCssWidgetStyleDeclarationClass))
+
+typedef struct _GtkCssWidgetStyleDeclaration           GtkCssWidgetStyleDeclaration;
+typedef struct _GtkCssWidgetStyleDeclarationClass      GtkCssWidgetStyleDeclarationClass;
+
+struct _GtkCssWidgetStyleDeclaration
+{
+  GtkCssDeclaration parent;
+};
+
+struct _GtkCssWidgetStyleDeclarationClass
+{
+  GtkCssDeclarationClass parent_class;
+};
+
+GType                   gtk_css_widget_style_declaration_get_type       (void) G_GNUC_CONST;
+  
+gboolean                gtk_css_widget_style_declaration_accepts_name   (const char                     
*name);
+
+GtkCssDeclaration *     gtk_css_widget_style_declaration_new_parse      (GtkCssStyleDeclaration         
*style,
+                                                                         GtkCssTokenSource              
*source);
+
+
+G_END_DECLS
+
+#endif /* __GTK_CSS_WIDGET_STYLE_DECLARATION_PRIVATE_H__ */


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