summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBenjamin Otte <otte@redhat.com>2016-03-27 06:22:43 +0200
committerBenjamin Otte <otte@redhat.com>2016-04-08 16:18:31 +0200
commitfabc1f633d17084bea28ad937139beb0ac0304a3 (patch)
tree0cef85ae9073d1535c1b58a5f054004c52a24732
parent01b320f563cd00ec6498d51383951f947dab4576 (diff)
downloadgtk+-fabc1f633d17084bea28ad937139beb0ac0304a3.tar.gz
cssprovider: Add a way to load a provider from a stylesheet
Use that way in the CSS editor.
-rw-r--r--gtk/gtkcssprovider.c122
-rw-r--r--gtk/gtkcssproviderprivate.h5
-rw-r--r--gtk/inspector/css-editor.c14
3 files changed, 127 insertions, 14 deletions
diff --git a/gtk/gtkcssprovider.c b/gtk/gtkcssprovider.c
index 2c72034f5d..96efc3430c 100644
--- a/gtk/gtkcssprovider.c
+++ b/gtk/gtkcssprovider.c
@@ -28,12 +28,20 @@
#include "gtkbitmaskprivate.h"
#include "gtkcssarrayvalueprivate.h"
#include "gtkcsscolorvalueprivate.h"
+#include "gtkcssdefinecolorruleprivate.h"
+#include "gtkcssdeclarationprivate.h"
+#include "gtkcssimportruleprivate.h"
#include "gtkcsskeyframesprivate.h"
+#include "gtkcsskeyframesruleprivate.h"
+#include "gtkcsslonghanddeclarationprivate.h"
#include "gtkcssparserprivate.h"
#include "gtkcsssectionprivate.h"
#include "gtkcssselectorprivate.h"
-#include "gtkcssshorthandpropertyprivate.h"
+#include "gtkcssshorthanddeclarationprivate.h"
#include "gtkcssstylefuncsprivate.h"
+#include "gtkcssstylepropertyprivate.h"
+#include "gtkcssstyleruleprivate.h"
+#include "gtkcsswidgetstyledeclarationprivate.h"
#include "gtksettingsprivate.h"
#include "gtkstyleprovider.h"
#include "gtkstylecontextprivate.h"
@@ -296,7 +304,7 @@ widget_property_value_new (char *name, GtkCssSection *section)
value = g_slice_new0 (WidgetPropertyValue);
value->name = name;
- if (gtk_keep_css_sections)
+ if (gtk_keep_css_sections && section)
value->section = gtk_css_section_ref (section);
return value;
@@ -395,7 +403,7 @@ gtk_css_ruleset_add (GtkCssRuleset *ruleset,
}
ruleset->styles[i].value = value;
- if (gtk_keep_css_sections)
+ if (gtk_keep_css_sections && section)
ruleset->styles[i].section = gtk_css_section_ref (section);
else
ruleset->styles[i].section = NULL;
@@ -1715,6 +1723,114 @@ gtk_css_provider_postprocess (GtkCssProvider *css_provider)
#endif
}
+static void
+gtk_css_provider_load_rules (GtkCssProvider *provider,
+ GtkCssRuleList *list)
+{
+ GtkCssRule *rule;
+ gsize i;
+
+ for (i = 0; i < gtk_css_rule_list_get_length (list); i++)
+ {
+ rule = gtk_css_rule_list_get_item (list, i);
+
+ if (GTK_IS_CSS_DEFINE_COLOR_RULE (rule))
+ {
+ GtkCssDefineColorRule *color_rule = GTK_CSS_DEFINE_COLOR_RULE (rule);
+
+ g_hash_table_insert (provider->priv->symbolic_colors,
+ g_strdup (gtk_css_define_color_rule_get_name (color_rule)),
+ _gtk_css_value_ref (gtk_css_define_color_rule_get_value (color_rule)));
+ }
+ else if (GTK_IS_CSS_IMPORT_RULE (rule))
+ {
+ GtkCssStyleSheet *style_sheet = gtk_css_import_rule_get_style_sheet (GTK_CSS_IMPORT_RULE (rule));
+ gtk_css_provider_load_rules (provider, gtk_css_style_sheet_get_css_rules (style_sheet));
+ }
+ else if (GTK_IS_CSS_KEYFRAMES_RULE (rule))
+ {
+ g_hash_table_insert (provider->priv->keyframes,
+ g_strdup (gtk_css_keyframes_rule_get_name (GTK_CSS_KEYFRAMES_RULE (rule))),
+ gtk_css_keyframes_new_from_rule (GTK_CSS_KEYFRAMES_RULE (rule)));
+ }
+ else if (GTK_IS_CSS_STYLE_RULE (rule))
+ {
+ GtkCssStyleDeclaration *style = gtk_css_style_rule_get_style (GTK_CSS_STYLE_RULE (rule));
+ GtkCssRuleset ruleset = { 0, };
+ guint j;
+
+ for (j = 0; j < gtk_css_style_declaration_get_length (style); j++)
+ {
+ GtkCssDeclaration *decl = gtk_css_style_declaration_get_declaration (style, j);
+
+ if (GTK_IS_CSS_LONGHAND_DECLARATION (decl))
+ {
+ GtkCssLonghandDeclaration *longhand = GTK_CSS_LONGHAND_DECLARATION (decl);
+ gtk_css_ruleset_add (&ruleset,
+ gtk_css_longhand_declaration_get_property (longhand),
+ _gtk_css_value_ref (gtk_css_longhand_declaration_get_value (longhand)),
+ NULL);
+ }
+ else if (GTK_IS_CSS_SHORTHAND_DECLARATION (decl))
+ {
+ GtkCssShorthandDeclaration *shorthand = GTK_CSS_SHORTHAND_DECLARATION (decl);
+ guint k;
+
+ for (k = 0; k < gtk_css_shorthand_declaration_get_length (shorthand); k++)
+ {
+ gtk_css_ruleset_add (&ruleset,
+ gtk_css_shorthand_declaration_get_subproperty (shorthand, k),
+ _gtk_css_value_ref (gtk_css_shorthand_declaration_get_value (shorthand, k)),
+ NULL);
+ }
+ }
+ else if (GTK_IS_CSS_WIDGET_STYLE_DECLARATION (decl))
+ {
+ WidgetPropertyValue *val;
+
+ val = widget_property_value_new (g_strdup (gtk_css_declaration_get_name (decl)), NULL);
+ val->value = gtk_css_declaration_get_value_string (decl);
+
+ gtk_css_ruleset_add_style (&ruleset, val->name, val);
+ }
+ }
+
+ if (ruleset.styles != NULL || ruleset.widget_style != NULL)
+ {
+ for (j = 0; j < gtk_css_style_rule_get_n_selectors (GTK_CSS_STYLE_RULE (rule)); j++)
+ {
+ GtkCssRuleset new;
+
+ gtk_css_ruleset_init_copy (&new,
+ &ruleset,
+ gtk_css_style_rule_get_selector (GTK_CSS_STYLE_RULE (rule), j));
+
+ g_array_append_val (provider->priv->rulesets, new);
+ }
+ }
+
+ gtk_css_ruleset_clear (&ruleset);
+ }
+ else
+ {
+ g_warning ("No code to deal with %s", G_OBJECT_TYPE_NAME (rule));
+ }
+ }
+}
+
+void
+gtk_css_provider_load_style_sheet (GtkCssProvider *provider,
+ GtkCssStyleSheet *style_sheet)
+{
+ gtk_css_provider_reset (provider);
+
+ gtk_css_provider_load_rules (provider, gtk_css_style_sheet_get_css_rules (style_sheet));
+
+ gtk_css_provider_postprocess (provider);
+
+ _gtk_style_provider_private_changed (GTK_STYLE_PROVIDER_PRIVATE (provider));
+}
+
static gboolean
gtk_css_provider_load_internal (GtkCssProvider *css_provider,
GtkCssScanner *parent,
diff --git a/gtk/gtkcssproviderprivate.h b/gtk/gtkcssproviderprivate.h
index bca8e79464..679f3721f7 100644
--- a/gtk/gtkcssproviderprivate.h
+++ b/gtk/gtkcssproviderprivate.h
@@ -20,6 +20,8 @@
#include "gtkcssprovider.h"
+#include "gtkcssstylesheetprivate.h"
+
G_BEGIN_DECLS
gchar *_gtk_get_theme_dir (void);
@@ -30,6 +32,9 @@ void _gtk_css_provider_load_named (GtkCssProvider *provider,
const gchar *name,
const gchar *variant);
+void gtk_css_provider_load_style_sheet (GtkCssProvider *provider,
+ GtkCssStyleSheet *style_sheet);
+
void gtk_css_provider_set_keep_css_sections (void);
G_END_DECLS
diff --git a/gtk/inspector/css-editor.c b/gtk/inspector/css-editor.c
index da004461df..b6b86d3823 100644
--- a/gtk/inspector/css-editor.c
+++ b/gtk/inspector/css-editor.c
@@ -29,6 +29,7 @@
#include "gtkcssdeclarationprivate.h"
#include "gtkcssprovider.h"
+#include "gtkcssproviderprivate.h"
#include "gtkcssrbtreeprivate.h"
#include "gtkcssstyleruleprivate.h"
#include "gtkcssstylesheetprivate.h"
@@ -479,6 +480,8 @@ update_style_sheet (GtkInspectorCssEditor *ce)
gtk_css_token_source_unref (source);
+ gtk_css_provider_load_style_sheet (ce->priv->provider, ce->priv->style_sheet);
+
gtk_inspector_css_rule_view_set_style_sheet (GTK_INSPECTOR_CSS_RULE_VIEW (ce->priv->ruleview),
ce->priv->style_sheet);
}
@@ -690,16 +693,6 @@ update_tokenize (GtkInspectorCssEditor *ce)
}
static void
-update_style (GtkInspectorCssEditor *ce)
-{
- gchar *text;
-
- text = get_current_text (ce->priv->text);
- gtk_css_provider_load_from_data (ce->priv->provider, text, -1, NULL);
- g_free (text);
-}
-
-static void
clear_all_tags (GtkInspectorCssEditor *ce)
{
GtkTextIter start, end;
@@ -717,7 +710,6 @@ update_timeout (gpointer data)
ce->priv->timeout = 0;
clear_all_tags (ce);
- update_style (ce);
update_tokenize (ce);
update_style_sheet (ce);
update_token_tags (ce, gtk_css_rb_tree_get_first (ce->priv->tokens), NULL);