[gtk+] API: css: Add GtkCssSection



commit 00d14e35157d7512ec9892bcc5eebdc186ad52e3
Author: Benjamin Otte <otte redhat com>
Date:   Fri Jun 17 02:02:24 2011 +0200

    API: css: Add GtkCssSection
    
    This struct keeps track of an area of text in a CSS file and uses it
    when specifying information. Also, the cssprovider keeps track of
    sections when parsing a file.

 docs/reference/gtk/gtk3-sections.txt |   14 ++
 gtk/Makefile.am                      |    3 +
 gtk/gtk.h                            |    1 +
 gtk/gtk.symbols                      |   10 ++
 gtk/gtkcssprovider.c                 |  136 ++++++++++++++--
 gtk/gtkcsssection.c                  |  291 ++++++++++++++++++++++++++++++++++
 gtk/gtkcsssection.h                  |   82 ++++++++++
 gtk/gtkcsssectionprivate.h           |   38 +++++
 8 files changed, 558 insertions(+), 17 deletions(-)
---
diff --git a/docs/reference/gtk/gtk3-sections.txt b/docs/reference/gtk/gtk3-sections.txt
index 7ec6f1d..2cc0722 100644
--- a/docs/reference/gtk/gtk3-sections.txt
+++ b/docs/reference/gtk/gtk3-sections.txt
@@ -5739,6 +5739,19 @@ gtk_css_provider_new
 gtk_css_provider_to_string
 GTK_CSS_PROVIDER_ERROR
 GtkCssProviderError
+<SUBSECTION>
+GtkCssSection
+GtkCssSectionType
+gtk_css_section_get_end_line
+gtk_css_section_get_end_position
+gtk_css_section_get_file
+gtk_css_section_get_parent
+gtk_css_section_get_section_type
+gtk_css_section_get_start_line
+gtk_css_section_get_start_position
+gtk_css_section_get_type
+gtk_css_section_ref
+gtk_css_section_unref
 <SUBSECTION Standard>
 GTK_TYPE_CSS_PROVIDER
 GTK_CSS_PROVIDER
@@ -5749,6 +5762,7 @@ GTK_IS_CSS_PROVIDER_CLASS
 <SUBSECTION Private>
 gtk_css_provider_get_type
 gtk_css_provider_error_quark
+gtk_css_section_get_type
 </SECTION>
 
 <SECTION>
diff --git a/gtk/Makefile.am b/gtk/Makefile.am
index ec3ff04..f6d6ee1 100644
--- a/gtk/Makefile.am
+++ b/gtk/Makefile.am
@@ -199,6 +199,7 @@ gtk_public_h_sources = 		\
 	gtkcomboboxtext.h	\
 	gtkcontainer.h		\
 	gtkcssprovider.h	\
+	gtkcsssection.h 	\
 	gtkdebug.h		\
 	gtkdialog.h		\
 	gtkdnd.h		\
@@ -394,6 +395,7 @@ gtk_private_h_sources =		\
 	gtkcontainerprivate.h   \
 	gtkcssparserprivate.h	\
 	gtkcssproviderprivate.h	\
+	gtkcsssectionprivate.h 	\
 	gtkcssselectorprivate.h	\
 	gtkcsstypesprivate.h	\
 	gtkcustompaperunixdialog.h \
@@ -526,6 +528,7 @@ gtk_base_c_sources = 		\
 	gtkcontainer.c		\
 	gtkcssparser.c		\
 	gtkcssprovider.c	\
+	gtkcsssection.c 	\
 	gtkcssselector.c	\
 	gtkcsstypes.c		\
 	gtkdialog.c		\
diff --git a/gtk/gtk.h b/gtk/gtk.h
index 7e2526e..a2813e9 100644
--- a/gtk/gtk.h
+++ b/gtk/gtk.h
@@ -82,6 +82,7 @@
 #include <gtk/gtkcomboboxtext.h>
 #include <gtk/gtkcontainer.h>
 #include <gtk/gtkcssprovider.h>
+#include <gtk/gtkcsssection.h>
 #include <gtk/gtkdebug.h>
 #include <gtk/gtkdialog.h>
 #include <gtk/gtkdnd.h>
diff --git a/gtk/gtk.symbols b/gtk/gtk.symbols
index 2c95bdf..9a42c01 100644
--- a/gtk/gtk.symbols
+++ b/gtk/gtk.symbols
@@ -701,6 +701,16 @@ gtk_css_provider_load_from_file
 gtk_css_provider_load_from_path
 gtk_css_provider_new
 gtk_css_provider_to_string
+gtk_css_section_get_end_line
+gtk_css_section_get_end_position
+gtk_css_section_get_file
+gtk_css_section_get_parent
+gtk_css_section_get_section_type
+gtk_css_section_get_start_line
+gtk_css_section_get_start_position
+gtk_css_section_get_type
+gtk_css_section_ref
+gtk_css_section_unref
 #ifdef G_OS_UNIX
 gtk_custom_paper_unix_dialog_get_type
 #endif
diff --git a/gtk/gtkcssprovider.c b/gtk/gtkcssprovider.c
index 9846185..30c5b79 100644
--- a/gtk/gtkcssprovider.c
+++ b/gtk/gtkcssprovider.c
@@ -28,6 +28,7 @@
 #include "gtkcssproviderprivate.h"
 
 #include "gtkcssparserprivate.h"
+#include "gtkcsssectionprivate.h"
 #include "gtkcssselectorprivate.h"
 #include "gtksymboliccolor.h"
 #include "gtkstyleprovider.h"
@@ -964,6 +965,7 @@ struct _GtkCssScanner
 {
   GtkCssProvider *provider;
   GtkCssParser *parser;
+  GSList *sections;
   GtkCssScanner *parent;
   GFile *file;
   GFile *base;
@@ -1237,6 +1239,8 @@ gtk_css_scanner_reset (GtkCssScanner *scanner)
 static void
 gtk_css_scanner_destroy (GtkCssScanner *scanner)
 {
+  g_assert (scanner->sections == NULL);
+
   gtk_css_scanner_reset (scanner);
 
   g_object_unref (scanner->provider);
@@ -1326,6 +1330,40 @@ gtk_css_scanner_would_recurse (GtkCssScanner *scanner,
 }
 
 static void
+gtk_css_scanner_push_section (GtkCssScanner     *scanner,
+                              GtkCssSectionType  section_type)
+{
+  GtkCssSection *parent, *section;
+
+  if (scanner->sections)
+    parent = scanner->sections->data;
+  else if (scanner->parent)
+    parent = scanner->parent->sections->data;
+  else
+    parent = NULL;
+
+  section = _gtk_css_section_new (parent,
+                                  section_type,
+                                  scanner->parser,
+                                  scanner->file);
+  scanner->sections = g_slist_prepend (scanner->sections, section);
+}
+
+static void
+gtk_css_scanner_pop_section (GtkCssScanner *scanner,
+                             GtkCssSectionType check_type)
+{
+  GtkCssSection *section = scanner->sections->data;
+  
+  g_assert (check_type == gtk_css_section_get_section_type (section));
+
+  scanner->sections = g_slist_delete_link (scanner->sections, scanner->sections);
+
+  _gtk_css_section_end (section);
+  gtk_css_section_unref (section);
+}
+
+static void
 gtk_css_provider_init (GtkCssProvider *css_provider)
 {
   GtkCssProviderPrivate *priv;
@@ -1664,20 +1702,30 @@ gtk_css_provider_propagate_error (GtkCssProvider  *provider,
   g_prefix_error (propagate_to, "%s:%u:%u: ", path ? path : "<unknown>", line, position);
 }
 
-static void
+static gboolean
 parse_import (GtkCssScanner *scanner)
 {
   GFile *file;
   char *uri;
 
+  gtk_css_scanner_push_section (scanner, GTK_CSS_SECTION_IMPORT);
+
+  if (!_gtk_css_parser_try (scanner->parser, "@import", TRUE))
+    {
+      gtk_css_scanner_pop_section (scanner, GTK_CSS_SECTION_IMPORT);
+      return FALSE;
+    }
+
   if (_gtk_css_parser_is_string (scanner->parser))
     uri = _gtk_css_parser_read_string (scanner->parser);
   else
     uri = _gtk_css_parser_read_uri (scanner->parser);
+
   if (uri == NULL)
     {
       _gtk_css_parser_resync (scanner->parser, TRUE, 0);
-      return;
+      gtk_css_scanner_pop_section (scanner, GTK_CSS_SECTION_IMPORT);
+      return TRUE;
     }
 
   file = g_file_resolve_relative_path (gtk_css_scanner_get_base_url (scanner), uri);
@@ -1705,21 +1753,30 @@ parse_import (GtkCssScanner *scanner)
 
   if (!_gtk_css_parser_try (scanner->parser, ";", TRUE))
     {
-      g_object_unref (file);
       gtk_css_provider_invalid_token (scanner->provider, scanner, "semicolon");
       _gtk_css_parser_resync (scanner->parser, TRUE, 0);
-      return;
     }
 
   g_object_unref (file);
+
+  gtk_css_scanner_pop_section (scanner, GTK_CSS_SECTION_IMPORT);
+  return TRUE;
 }
 
-static void
+static gboolean
 parse_color_definition (GtkCssScanner *scanner)
 {
   GtkSymbolicColor *symbolic;
   char *name;
 
+  gtk_css_scanner_push_section (scanner, GTK_CSS_SECTION_COLOR_DEFINITION);
+
+  if (!_gtk_css_parser_try (scanner->parser, "@define-color", TRUE))
+    {
+      gtk_css_scanner_pop_section (scanner, GTK_CSS_SECTION_COLOR_DEFINITION);
+      return FALSE;
+    }
+
   name = _gtk_css_parser_try_name (scanner->parser, TRUE);
   if (name == NULL)
     {
@@ -1729,7 +1786,8 @@ parse_color_definition (GtkCssScanner *scanner)
                                       GTK_CSS_PROVIDER_ERROR_SYNTAX,
                                       "Not a valid color name");
       _gtk_css_parser_resync (scanner->parser, TRUE, 0);
-      return;
+      gtk_css_scanner_pop_section (scanner, GTK_CSS_SECTION_COLOR_DEFINITION);
+      return TRUE;
     }
 
   symbolic = _gtk_css_parser_read_symbolic_color (scanner->parser);
@@ -1737,7 +1795,8 @@ parse_color_definition (GtkCssScanner *scanner)
     {
       g_free (name);
       _gtk_css_parser_resync (scanner->parser, TRUE, 0);
-      return;
+      gtk_css_scanner_pop_section (scanner, GTK_CSS_SECTION_COLOR_DEFINITION);
+      return TRUE;
     }
 
   if (!_gtk_css_parser_try (scanner->parser, ";", TRUE))
@@ -1750,18 +1809,31 @@ parse_color_definition (GtkCssScanner *scanner)
                                       GTK_CSS_PROVIDER_ERROR_SYNTAX,
                                       "Missing semicolon at end of color definition");
       _gtk_css_parser_resync (scanner->parser, TRUE, 0);
-      return;
+
+      gtk_css_scanner_pop_section (scanner, GTK_CSS_SECTION_COLOR_DEFINITION);
+      return TRUE;
     }
 
   g_hash_table_insert (scanner->provider->priv->symbolic_colors, name, symbolic);
+
+  gtk_css_scanner_pop_section (scanner, GTK_CSS_SECTION_COLOR_DEFINITION);
+  return TRUE;
 }
 
-static void
+static gboolean
 parse_binding_set (GtkCssScanner *scanner)
 {
   GtkBindingSet *binding_set;
   char *name;
 
+  gtk_css_scanner_push_section (scanner, GTK_CSS_SECTION_BINDING_SET);
+
+  if (!_gtk_css_parser_try (scanner->parser, "@binding-set", TRUE))
+    {
+      gtk_css_scanner_pop_section (scanner, GTK_CSS_SECTION_BINDING_SET);
+      return FALSE;
+    }
+
   name = _gtk_css_parser_try_ident (scanner->parser, TRUE);
   if (name == NULL)
     {
@@ -1850,17 +1922,22 @@ skip_semicolon:
                                       "Nonstandard semicolon at end of binding set");
       _gtk_css_parser_try (scanner->parser, ";", TRUE);
     }
+
+  gtk_css_scanner_pop_section (scanner, GTK_CSS_SECTION_BINDING_SET);
+
+  return TRUE;
 }
 
 static void
 parse_at_keyword (GtkCssScanner *scanner)
 {
-  if (_gtk_css_parser_try (scanner->parser, "@import", TRUE))
-    parse_import (scanner);
-  else if (_gtk_css_parser_try (scanner->parser, "@define-color", TRUE))
-    parse_color_definition (scanner);
-  else if (_gtk_css_parser_try (scanner->parser, "@binding-set", TRUE))
-    parse_binding_set (scanner);
+  if (parse_import (scanner))
+    return;
+  if (parse_color_definition (scanner))
+    return;
+  if (parse_binding_set (scanner))
+    return;
+
   else
     {
       gtk_css_provider_error_literal (scanner->provider,
@@ -2152,6 +2229,8 @@ parse_selector_list (GtkCssScanner *scanner)
 {
   GSList *selectors = NULL;
 
+  gtk_css_scanner_push_section (scanner, GTK_CSS_SECTION_SELECTOR);
+
   do {
       GtkCssSelector *select = parse_selector (scanner);
 
@@ -2159,6 +2238,7 @@ parse_selector_list (GtkCssScanner *scanner)
         {
           g_slist_free_full (selectors, (GDestroyNotify) _gtk_css_selector_free);
           _gtk_css_parser_resync (scanner->parser, FALSE, 0);
+          gtk_css_scanner_pop_section (scanner, GTK_CSS_SECTION_SELECTOR);
           return NULL;
         }
 
@@ -2166,6 +2246,8 @@ parse_selector_list (GtkCssScanner *scanner)
     }
   while (_gtk_css_parser_try (scanner->parser, ",", TRUE));
 
+  gtk_css_scanner_pop_section (scanner, GTK_CSS_SECTION_SELECTOR);
+
   return selectors;
 }
 
@@ -2176,6 +2258,8 @@ parse_declaration (GtkCssScanner *scanner,
   const GtkStyleProperty *property;
   char *name;
 
+  gtk_css_scanner_push_section (scanner, GTK_CSS_SECTION_DECLARATION);
+
   name = _gtk_css_parser_try_ident (scanner->parser, TRUE);
   if (name == NULL)
     goto check_for_semicolon;
@@ -2191,6 +2275,7 @@ parse_declaration (GtkCssScanner *scanner,
                               name);
       _gtk_css_parser_resync (scanner->parser, TRUE, '}');
       g_free (name);
+      gtk_css_scanner_pop_section (scanner, GTK_CSS_SECTION_DECLARATION);
       return;
     }
 
@@ -2199,6 +2284,7 @@ parse_declaration (GtkCssScanner *scanner,
       gtk_css_provider_invalid_token (scanner->provider, scanner, "':'");
       _gtk_css_parser_resync (scanner->parser, TRUE, '}');
       g_free (name);
+      gtk_css_scanner_pop_section (scanner, GTK_CSS_SECTION_DECLARATION);
       return;
     }
 
@@ -2232,6 +2318,7 @@ parse_declaration (GtkCssScanner *scanner,
               _gtk_css_parser_resync (scanner->parser, TRUE, '}');
               g_value_unset (val);
               g_slice_free (GValue, val);
+              gtk_css_scanner_pop_section (scanner, GTK_CSS_SECTION_DECLARATION);
               return;
             }
         }
@@ -2240,6 +2327,7 @@ parse_declaration (GtkCssScanner *scanner,
           g_value_unset (val);
           g_slice_free (GValue, val);
           _gtk_css_parser_resync (scanner->parser, TRUE, '}');
+          gtk_css_scanner_pop_section (scanner, GTK_CSS_SECTION_DECLARATION);
           return;
         }
     }
@@ -2261,6 +2349,7 @@ parse_declaration (GtkCssScanner *scanner,
       else
         {
           _gtk_css_parser_resync (scanner->parser, TRUE, '}');
+          gtk_css_scanner_pop_section (scanner, GTK_CSS_SECTION_DECLARATION);
           return;
         }
     }
@@ -2268,6 +2357,8 @@ parse_declaration (GtkCssScanner *scanner,
     g_free (name);
 
 check_for_semicolon:
+  gtk_css_scanner_pop_section (scanner, GTK_CSS_SECTION_DECLARATION);
+
   if (!_gtk_css_parser_try (scanner->parser, ";", TRUE))
     {
       if (!_gtk_css_parser_begins_with (scanner->parser, '}') &&
@@ -2300,9 +2391,14 @@ parse_ruleset (GtkCssScanner *scanner)
   GSList *selectors;
   GtkCssRuleset ruleset = { 0, };
 
+  gtk_css_scanner_push_section (scanner, GTK_CSS_SECTION_RULESET);
+
   selectors = parse_selector_list (scanner);
   if (selectors == NULL)
-    return;
+    {
+      gtk_css_scanner_pop_section (scanner, GTK_CSS_SECTION_RULESET);
+      return;
+    }
 
   if (!_gtk_css_parser_try (scanner->parser, "{", TRUE))
     {
@@ -2313,6 +2409,7 @@ parse_ruleset (GtkCssScanner *scanner)
                                       "expected '{' after selectors");
       _gtk_css_parser_resync (scanner->parser, FALSE, 0);
       g_slist_free_full (selectors, (GDestroyNotify) _gtk_css_selector_free);
+      gtk_css_scanner_pop_section (scanner, GTK_CSS_SECTION_RULESET);
       return;
     }
 
@@ -2330,12 +2427,13 @@ parse_ruleset (GtkCssScanner *scanner)
           _gtk_css_parser_resync (scanner->parser, FALSE, 0);
           g_slist_free_full (selectors, (GDestroyNotify) _gtk_css_selector_free);
           gtk_css_ruleset_clear (&ruleset);
-          return;
+          gtk_css_scanner_pop_section (scanner, GTK_CSS_SECTION_RULESET);
         }
     }
 
   css_provider_commit (scanner->provider, selectors, &ruleset);
   gtk_css_ruleset_clear (&ruleset);
+  gtk_css_scanner_pop_section (scanner, GTK_CSS_SECTION_RULESET);
 }
 
 static void
@@ -2350,6 +2448,8 @@ parse_statement (GtkCssScanner *scanner)
 static void
 parse_stylesheet (GtkCssScanner *scanner)
 {
+  gtk_css_scanner_push_section (scanner, GTK_CSS_SECTION_DOCUMENT);
+
   _gtk_css_parser_skip_whitespace (scanner->parser);
 
   while (!_gtk_css_parser_is_eof (scanner->parser))
@@ -2360,6 +2460,8 @@ parse_stylesheet (GtkCssScanner *scanner)
 
       parse_statement (scanner);
     }
+
+  gtk_css_scanner_pop_section (scanner, GTK_CSS_SECTION_DOCUMENT);
 }
 
 static int
diff --git a/gtk/gtkcsssection.c b/gtk/gtkcsssection.c
new file mode 100644
index 0000000..4b1d0e5
--- /dev/null
+++ b/gtk/gtkcsssection.c
@@ -0,0 +1,291 @@
+/* GTK - The GIMP Toolkit
+ * Copyright (C) 2011 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 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, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#include "config.h"
+
+#include "gtkcsssectionprivate.h"
+
+#include "gtkcssparserprivate.h"
+
+/**
+ * GtkCssSection:
+ *
+ * Defines a part of a CSS document. Because sections are nested into
+ * one another, you can use gtk_css_section_get_parent() to get the
+ * containing region.
+ *
+ * Since: 3.2
+ */
+
+struct _GtkCssSection
+{
+  volatile gint       ref_count;
+  GtkCssSectionType   section_type;
+  GtkCssSection      *parent;
+  GFile              *file;
+  guint               start_line;
+  guint               start_position;
+  GtkCssParser       *parser;         /* parser if section isn't finished parsing yet or %NULL */
+  guint               end_line;       /* end line if parser is %NULL */
+  guint               end_position;   /* end position if parser is %NULL */
+};
+
+G_DEFINE_BOXED_TYPE (GtkCssSection, gtk_css_section, gtk_css_section_ref, gtk_css_section_unref)
+
+GtkCssSection *
+_gtk_css_section_new (GtkCssSection     *parent,
+                      GtkCssSectionType  type,
+                      GtkCssParser      *parser,
+                      GFile             *file)
+{
+  GtkCssSection *section;
+
+  g_return_val_if_fail (parser != NULL, NULL);
+  g_return_val_if_fail (file == NULL || G_IS_FILE (file), NULL);
+
+  section = g_slice_new0 (GtkCssSection);
+
+  section->ref_count = 1;
+  section->section_type = type;
+  if (parent)
+    section->parent = gtk_css_section_ref (parent);
+  if (file)
+    section->file = g_object_ref (file);
+  section->start_line = _gtk_css_parser_get_line (parser);
+  section->start_position = _gtk_css_parser_get_position (parser);
+  section->parser = parser;
+
+  return section;
+}
+
+void
+_gtk_css_section_end (GtkCssSection *section)
+{
+  g_return_if_fail (section != NULL);
+  g_return_if_fail (section->parser != NULL);
+
+  section->end_line = _gtk_css_parser_get_line (section->parser);
+  section->end_position = _gtk_css_parser_get_position (section->parser);
+  section->parser = NULL;
+}
+
+/**
+ * gtk_css_section_ref:
+ * @section: a #GtkCssSection
+ *
+ * Increments the reference count on @section.
+ *
+ * Returns: @section itself.
+ *
+ * Since: 3.2
+ **/
+GtkCssSection *
+gtk_css_section_ref (GtkCssSection *section)
+{
+  g_return_val_if_fail (section != NULL, NULL);
+
+  g_atomic_int_add (&section->ref_count, 1);
+
+  return section;
+}
+
+/**
+ * gtk_css_section_unref:
+ * @section: a #GtkCssSection
+ *
+ * Decrements the reference count on @section, freeing the
+ * structure if the reference count reaches 0.
+ *
+ * Since: 3.2
+ **/
+void
+gtk_css_section_unref (GtkCssSection *section)
+{
+  g_return_if_fail (section != NULL);
+
+  if (!g_atomic_int_dec_and_test (&section->ref_count))
+    return;
+
+  if (section->parent)
+    gtk_css_section_unref (section->parent);
+  if (section->file)
+    g_object_unref (section->file);
+
+  g_slice_free (GtkCssSection, section);
+}
+
+/**
+ * gtk_css_section_get_section_type:
+ * @section: the section
+ *
+ * Gets the type of information that @section describes.
+ *
+ * Returns: the type of @section
+ *
+ * Since: 3.2
+ **/
+GtkCssSectionType
+gtk_css_section_get_section_type (const GtkCssSection *section)
+{
+  g_return_val_if_fail (section != NULL, GTK_CSS_SECTION_DOCUMENT);
+
+  return section->section_type;
+}
+
+/**
+ * gtk_css_section_get_parent:
+ * @section: the section
+ *
+ * Gets the parent section for the given @section. The parent section is
+ * the section that contains this @section. A special case are sections of
+ * type #GTK_CSS_SECTION_TYPE_DOCUMENT. Their parent will either be %NULL
+ * if they are the original CSS document that was loaded by
+ * gtk_css_provider_load_from_file() or a section of type
+ * #GTK_CSS_SECTION_TYPE_IMPORT if it was loaded with an import rule from
+ * a different file.
+ *
+ * Returns: the parent section or %NULL if none
+ *
+ * Since: 3.2
+ **/
+GtkCssSection *
+gtk_css_section_get_parent (const GtkCssSection *section)
+{
+  g_return_val_if_fail (section != NULL, NULL);
+
+  return section->parent;
+}
+
+/**
+ * gtk_css_section_get_file:
+ * @section: the section
+ *
+ * Gets the file that @section was parsed from. If no such file exists,
+ * for example because the CSS was loaded via 
+ * @gtk_css_provider_load_from_data(), then %NULL is returned.
+ *
+ * Returns: the #GFile that @section was parsed from or %NULL if
+ *   @section was parsed from other data.
+ *
+ * Since: 3.2
+ **/
+GFile *
+gtk_css_section_get_file (const GtkCssSection *section)
+{
+  g_return_val_if_fail (section != NULL, NULL);
+
+  return section->file;
+}
+
+/**
+ * gtk_css_section_get_start_line:
+ * @section: the section
+ *
+ * Returns the line in the CSS document where this section starts.
+ * The line number is 0-indexed, so the first line of the document
+ * will return 0.
+ *
+ * Returns: the line number
+ *
+ * Since: 3.2
+ **/
+guint
+gtk_css_section_get_start_line (const GtkCssSection *section)
+{
+  g_return_val_if_fail (section != NULL, 0);
+
+  return section->start_line;
+}
+
+/**
+ * gtk_css_section_get_start_position:
+ * @section: the section
+ *
+ * Returns the offset in bytes from the start of the current line
+ * returned via gtk_css_section_get_start_line().
+ *
+ * Returns: the offset in bytes from the start of the line.
+ *
+ * Since: 3.2
+ **/
+guint
+gtk_css_section_get_start_position (const GtkCssSection *section)
+{
+  g_return_val_if_fail (section != NULL, 0);
+
+  return section->start_position;
+}
+
+/**
+ * gtk_css_section_get_end_line:
+ * @section: the section
+ *
+ * Returns the line in the CSS document where this section end.
+ * The line number is 0-indexed, so the first line of the document
+ * will return 0.
+ * This value may change in future invocations of this function if
+ * @section is not yet parsed completely. This will for example 
+ * happen in the GtkCssProvider::parsing-error signal.
+ * The end position and line may be identical to the start
+ * position and line for sections which failed to parse anything
+ * successfully.
+ *
+ * Returns: the line number
+ *
+ * Since: 3.2
+ **/
+guint
+gtk_css_section_get_end_line (const GtkCssSection *section)
+{
+  g_return_val_if_fail (section != NULL, 0);
+
+  if (section->parser)
+    return _gtk_css_parser_get_line (section->parser);
+  else
+    return section->end_line;
+}
+
+/**
+ * gtk_css_section_get_start_position:
+ * @section: the section
+ *
+ * Returns the offset in bytes from the start of the current line
+ * returned via gtk_css_section_get_end_line().
+ * This value may change in future invocations of this function if
+ * @section is not yet parsed completely. This will for example 
+ * happen in the GtkCssProvider::parsing-error signal.
+ * The end position and line may be identical to the start
+ * position and line for sections which failed to parse anything
+ * successfully.
+ *
+ * Returns: the offset in bytes from the start of the line.
+ *
+ * Since: 3.2
+ **/
+guint
+gtk_css_section_get_end_position (const GtkCssSection *section)
+{
+  g_return_val_if_fail (section != NULL, 0);
+
+  if (section->parser)
+    return _gtk_css_parser_get_position (section->parser);
+  else
+    return section->end_position;
+}
+
diff --git a/gtk/gtkcsssection.h b/gtk/gtkcsssection.h
new file mode 100644
index 0000000..761ebd1
--- /dev/null
+++ b/gtk/gtkcsssection.h
@@ -0,0 +1,82 @@
+/* GTK - The GIMP Toolkit
+ * Copyright (C) 2011 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 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, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef __GTK_CSS_SECTION_H__
+#define __GTK_CSS_SECTION_H__
+
+#include <gio/gio.h>
+
+G_BEGIN_DECLS
+
+#define GTK_TYPE_CSS_SECTION         (gtk_css_section_get_type ())
+
+/**
+ * GtkCssSection:
+ * @GTK_CSS_SECTION_DOCUMENT: The section describes a complete document.
+ *   This section time is the only one where gtk_css_section_get_parent()
+ *   might return %NULL.
+ * @GTK_CSS_SECTION_IMPORT: The section defines an import rule.
+ * @GTK_CSS_SECTION_COLOR_DEFINITION: The section defines a color. This
+ *   is a GTK extension to CSS.
+ * @GTK_CSS_SECTION_BINDING_SET: The section defines a binding set. This
+ *   is a GTK extension to CSS.
+ * @GTK_CSS_SECTION_RULESET: The section defines a CSS ruleset.
+ * @GTK_CSS_SECTION_SELECTOR: The section defines a CSS selector.
+ * @GTK_CSS_SECTION_DECLARATION: The section defines the declaration of
+ *   a CSS variable.
+ *
+ * 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
+ * <ulink url="http://www.w3.org/TR/CSS21/grammar.html";>CSS grammer</ulink>,
+ * but may contain extensions.
+ *
+ * More types might be added in the future as the parser incorporates
+ * more features.
+ *
+ * Since: 3.2
+ */
+typedef enum
+{
+  GTK_CSS_SECTION_DOCUMENT,
+  GTK_CSS_SECTION_IMPORT,
+  GTK_CSS_SECTION_COLOR_DEFINITION,
+  GTK_CSS_SECTION_BINDING_SET,
+  GTK_CSS_SECTION_RULESET,
+  GTK_CSS_SECTION_SELECTOR,
+  GTK_CSS_SECTION_DECLARATION,
+} GtkCssSectionType;
+
+typedef struct _GtkCssSection GtkCssSection;
+
+GType              gtk_css_section_get_type            (void) G_GNUC_CONST;
+
+GtkCssSection *    gtk_css_section_ref                 (GtkCssSection        *section);
+void               gtk_css_section_unref               (GtkCssSection        *section);
+
+GtkCssSectionType  gtk_css_section_get_section_type    (const GtkCssSection  *section);
+GtkCssSection *    gtk_css_section_get_parent          (const GtkCssSection  *section);
+GFile *            gtk_css_section_get_file            (const GtkCssSection  *section);
+guint              gtk_css_section_get_start_line      (const GtkCssSection  *section);
+guint              gtk_css_section_get_start_position  (const GtkCssSection  *section);
+guint              gtk_css_section_get_end_line        (const GtkCssSection  *section);
+guint              gtk_css_section_get_end_position    (const GtkCssSection  *section);
+
+G_END_DECLS
+
+#endif /* __GTK_CSS_SECTION_H__ */
diff --git a/gtk/gtkcsssectionprivate.h b/gtk/gtkcsssectionprivate.h
new file mode 100644
index 0000000..776fd5d
--- /dev/null
+++ b/gtk/gtkcsssectionprivate.h
@@ -0,0 +1,38 @@
+/* GTK - The GIMP Toolkit
+ * Copyright (C) 2011 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 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, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef __GTK_CSS_SECTION_PRIVATE_H__
+#define __GTK_CSS_SECTION_PRIVATE_H__
+
+#include "gtkcsssection.h"
+
+#include "gtkcssparserprivate.h"
+
+G_BEGIN_DECLS
+
+GtkCssSection *    _gtk_css_section_new                (GtkCssSection        *parent,
+                                                        GtkCssSectionType     type,
+                                                        GtkCssParser         *parser,
+                                                        GFile                *file);
+
+void               _gtk_css_section_end                (GtkCssSection        *section);
+
+G_END_DECLS
+
+#endif /* __GTK_CSS_SECTION_PRIVATE_H__ */



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