gtk+ r20152 - in trunk: . docs/reference/gtk/tmpl gtk



Author: tvb
Date: Sun May 25 15:12:39 2008
New Revision: 20152
URL: http://svn.gnome.org/viewvc/gtk+?rev=20152&view=rev

Log:

	* gtk/gtkbuilderprivate.h, gtk/gtkbuilder.h, gtk/gtkbuilderparser.c:
	Added support for parsing required toolkit versions (so that ui descriptions
	can target specific versions of the backend widget libraries) bug 527612.

	* gtk/docs/reference/gtk/tmpl/gtkbuilder.sgml: Added documentation
	for the added xml tags to the ui description.



Modified:
   trunk/ChangeLog
   trunk/docs/reference/gtk/tmpl/gtkbuilder.sgml
   trunk/gtk/gtkbuilder.h
   trunk/gtk/gtkbuilderparser.c
   trunk/gtk/gtkbuilderprivate.h

Modified: trunk/docs/reference/gtk/tmpl/gtkbuilder.sgml
==============================================================================
--- trunk/docs/reference/gtk/tmpl/gtkbuilder.sgml	(original)
+++ trunk/docs/reference/gtk/tmpl/gtkbuilder.sgml	Sun May 25 15:12:39 2008
@@ -50,10 +50,11 @@
 </para>
 <para>
 <programlisting><![CDATA[
-<!ELEMENT interface object* >
+<!ELEMENT interface (requires|object)* >
 <!ELEMENT object    (property|signal|child|ANY)* >
 <!ELEMENT property  PCDATA >
 <!ELEMENT signal    EMPTY >
+<!ELEMENT requires  EMPTY >
 <!ELEMENT child     (object|ANY*) >
 
 <!ATTLIST interface  domain         	    #IMPLIED >
@@ -61,6 +62,8 @@
                      class          	    #REQUIRED
                      type-func      	    #IMPLIED
                      constructor    	    #IMPLIED >
+<!ATTLIST requires   lib             	    #REQUIRED
+                     version          	    #REQUIRED >
 <!ATTLIST property   name           	    #REQUIRED
                      translatable   	    #IMPLIED 
                      comments               #IMPLIED
@@ -88,6 +91,11 @@
 inside a container, but also e.g. actions in an action group,
 or columns in a tree model). A &lt;child&gt; element contains
 an &lt;object&gt; element which describes the child object.
+The target toolkit version(s) are described by &lt;requires&gt;
+elements, the "lib" attribute specifies the widget library in
+question (currently the only supported value is "gtk+") and the "version" 
+attribute specifies the target version in the form "&lt;major&gt;.&lt;minor&gt;".
+The builder will error out if the version requirements are not met.
 </para>
 <para>
 Typically, the specific kind of object represented by an
@@ -258,6 +266,7 @@
 
 </para>
 
+ GTK_BUILDER_ERROR_VERSION_MISMATCH: 
 @GTK_BUILDER_ERROR_INVALID_TYPE_FUNCTION: 
 @GTK_BUILDER_ERROR_UNHANDLED_TAG: 
 @GTK_BUILDER_ERROR_MISSING_ATTRIBUTE: 

Modified: trunk/gtk/gtkbuilder.h
==============================================================================
--- trunk/gtk/gtkbuilder.h	(original)
+++ trunk/gtk/gtkbuilder.h	Sun May 25 15:12:39 2008
@@ -39,6 +39,7 @@
 
 typedef enum
 {
+  GTK_BUILDER_ERROR_VERSION_MISMATCH,
   GTK_BUILDER_ERROR_INVALID_TYPE_FUNCTION,
   GTK_BUILDER_ERROR_UNHANDLED_TAG,
   GTK_BUILDER_ERROR_MISSING_ATTRIBUTE,

Modified: trunk/gtk/gtkbuilderparser.c
==============================================================================
--- trunk/gtk/gtkbuilderparser.c	(original)
+++ trunk/gtk/gtkbuilderparser.c	Sun May 25 15:12:39 2008
@@ -28,6 +28,7 @@
 #include "gtkbuilder.h"
 #include "gtkbuildable.h"
 #include "gtkdebug.h"
+#include "gtkversion.h"
 #include "gtktypeutils.h"
 #include "gtkintl.h"
 #include "gtkalias.h"
@@ -225,6 +226,63 @@
 }
 
 static void
+parse_requires (ParserData   *data,
+		const gchar  *element_name,
+		const gchar **names,
+		const gchar **values,
+		GError      **error)
+{
+  RequiresInfo *req_info;
+  const gchar  *library = NULL;
+  const gchar  *version = NULL;
+  gchar       **split;
+  gint          i, version_major = 0, version_minor = 0;
+  gint          line_number, char_number;
+
+  g_markup_parse_context_get_position (data->ctx,
+                                       &line_number,
+                                       &char_number);
+
+  for (i = 0; names[i] != NULL; i++)
+    {
+      if (strcmp (names[i], "lib") == 0)
+        library = values[i];
+      else if (strcmp (names[i], "version") == 0)
+	version = values[i];
+      else
+	error_invalid_attribute (data, element_name, names[i], error);
+    }
+
+  if (!library || !version)
+    {
+      error_missing_attribute (data, element_name, 
+			       version ? "lib" : "version", error);
+      return;
+    }
+
+  if (!(split = g_strsplit (version, ".", 2)) || !split[0] || !split[1])
+    {
+      g_set_error (error,
+		   GTK_BUILDER_ERROR,
+		   GTK_BUILDER_ERROR_INVALID_VALUE,
+		   "%s:%d:%d <%s> attribute has malformed value \"%s\"",
+		   data->filename,
+		   line_number, char_number, "version", version);
+      return;
+    }
+  version_major = g_ascii_strtoll (split[0], NULL, 10);
+  version_minor = g_ascii_strtoll (split[1], NULL, 10);
+  g_strfreev (split);
+
+  req_info = g_slice_new0 (RequiresInfo);
+  req_info->library = g_strdup (library);
+  req_info->major   = version_major;
+  req_info->minor   = version_minor;
+  state_push (data, req_info);
+  req_info->tag.name = element_name;
+}
+
+static void
 parse_object (ParserData   *data,
               const gchar  *element_name,
               const gchar **names,
@@ -521,6 +579,14 @@
   g_slice_free (SignalInfo, info);
 }
 
+void
+_free_requires_info (RequiresInfo *info,
+		     gpointer user_data)
+{
+  g_free (info->library);
+  g_slice_free (RequiresInfo, info);
+}
+
 static void
 parse_interface (ParserData   *data,
 		 const gchar  *element_name,
@@ -729,8 +795,10 @@
     if (!subparser_start (context, element_name, names, values,
 			  data, error))
       return;
-  
-  if (strcmp (element_name, "object") == 0)
+
+  if (strcmp (element_name, "requires") == 0)
+    parse_requires (data, element_name, names, values, error);
+  else if (strcmp (element_name, "object") == 0)
     parse_object (data, element_name, names, values, error);
   else if (strcmp (element_name, "child") == 0)
     parse_child (data, element_name, names, values, error);
@@ -821,7 +889,27 @@
       return;
     }
 
-  if (strcmp (element_name, "object") == 0)
+  if (strcmp (element_name, "requires") == 0)
+    {
+      RequiresInfo *req_info = state_pop_info (data, RequiresInfo);
+
+      /* TODO: Allow third party widget developers to check thier
+       * required versions, possibly throw a signal allowing them
+       * to check thier library versions here.
+       */
+      if (!strcmp (req_info->library, "gtk+"))
+	{
+	  if (!GTK_CHECK_VERSION (req_info->major, req_info->minor, 0))
+	    g_set_error (error,
+			 GTK_BUILDER_ERROR,
+			 GTK_BUILDER_ERROR_VERSION_MISMATCH,
+			 "%s: required %s version %d.%d, current version is %d.%d",
+			 data->filename, req_info->library, 
+			 req_info->major, req_info->minor,
+			 GTK_MAJOR_VERSION, GTK_MINOR_VERSION);
+	}
+    }
+  else if (strcmp (element_name, "object") == 0)
     {
       ObjectInfo *object_info = state_pop_info (data, ObjectInfo);
       ChildInfo* child_info = state_peek_info (data, ChildInfo);
@@ -948,6 +1036,8 @@
     free_property_info ((PropertyInfo *)info);
   else if (strcmp (info->tag.name, "signal") == 0) 
     _free_signal_info ((SignalInfo *)info, NULL);
+  else if (strcmp (info->tag.name, "requires") == 0) 
+    _free_requires_info ((RequiresInfo *)info, NULL);
   else 
     g_assert_not_reached ();
 }

Modified: trunk/gtk/gtkbuilderprivate.h
==============================================================================
--- trunk/gtk/gtkbuilderprivate.h	(original)
+++ trunk/gtk/gtkbuilderprivate.h	Sun May 25 15:12:39 2008
@@ -72,6 +72,13 @@
 } SignalInfo;
 
 typedef struct {
+  TagInfo  tag;
+  gchar   *library;
+  gint     major;
+  gint     minor;
+} RequiresInfo;
+
+typedef struct {
   GMarkupParser *parser;
   gchar *tagname;
   const gchar *start;



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