[glibmm] Add support for GtkContainer child properties



commit 27ccef4d6f12c1fd3186578b790218d74afaa36b
Author: Juan R. GarcĂ­a Blanco <juanrgar gmail com>
Date:   Sun Jun 15 20:33:38 2014 +0200

    Add support for GtkContainer child properties

 tools/extra_defs_gen/generate_extra_defs.cc |   67 +++++++-----
 tools/extra_defs_gen/generate_extra_defs.h  |    3 +
 tools/pm/GtkDefs.pm                         |   31 ++++++
 tools/pm/Output.pm                          |  150 ++++++++++++++++-----------
 tools/pm/Property.pm                        |    2 +-
 tools/pm/WrapParser.pm                      |   28 +++++-
 6 files changed, 185 insertions(+), 96 deletions(-)
---
diff --git a/tools/extra_defs_gen/generate_extra_defs.cc b/tools/extra_defs_gen/generate_extra_defs.cc
index 52a35fe..f209348 100644
--- a/tools/extra_defs_gen/generate_extra_defs.cc
+++ b/tools/extra_defs_gen/generate_extra_defs.cc
@@ -23,6 +23,43 @@
 #include "generate_extra_defs.h"
 #include <algorithm>
 
+std::string get_property_with_node_name(GParamSpec* pParamSpec, const std::string& strObjectName, const 
std::string& strNodeName)
+{
+  std::string strResult;
+
+  //Name and type:
+  const std::string strName = g_param_spec_get_name(pParamSpec);
+  const std::string strTypeName = G_PARAM_SPEC_TYPE_NAME(pParamSpec);
+
+  const gchar* pchBlurb = g_param_spec_get_blurb(pParamSpec);
+  std::string strDocs = (pchBlurb) ? pchBlurb : "";
+  // Quick hack to get rid of nested double quotes:
+  std::replace(strDocs.begin(), strDocs.end(), '"', '\'');
+
+  strResult += "(" + strNodeName + " " + strName + "\n";
+  strResult += "  (of-object \"" + strObjectName + "\")\n";
+  strResult += "  (prop-type \"" + strTypeName + "\")\n";
+  strResult += "  (docs \"" + strDocs + "\")\n";
+
+  //Flags:
+  GParamFlags flags = pParamSpec->flags;
+  bool bReadable = (flags & G_PARAM_READABLE) == G_PARAM_READABLE;
+  bool bWritable = (flags & G_PARAM_WRITABLE) == G_PARAM_WRITABLE;
+  bool bConstructOnly = (flags & G_PARAM_CONSTRUCT_ONLY) == G_PARAM_CONSTRUCT_ONLY;
+
+  //#t and #f aren't documented, but I guess that it's correct based on the example in the .defs spec.
+  const std::string strTrue = "#t";
+  const std::string strFalse = "#f";
+
+  strResult += "  (readable " + (bReadable ? strTrue : strFalse) + ")\n";
+  strResult += "  (writable " + (bWritable ? strTrue : strFalse) + ")\n";
+  strResult += "  (construct-only " + (bConstructOnly ? strTrue : strFalse) + ")\n";
+
+  strResult += ")\n\n"; //close (strNodeName
+
+  return strResult;
+}
+
 // Until the glib bug https://bugzilla.gnome.org/show_bug.cgi?id=465631
 // is fixed, get_properties() must be called for a GObject before it's
 // called for a GInterface.
@@ -75,35 +112,7 @@ std::string get_properties(GType gtype)
     // The base classes' properties should not be generated).
     if(pParamSpec && pParamSpec->owner_type == gtype)
     {
-      //Name and type:
-      const std::string strName = g_param_spec_get_name(pParamSpec);
-      const std::string strTypeName = G_PARAM_SPEC_TYPE_NAME(pParamSpec);
-
-      const gchar* pchBlurb = g_param_spec_get_blurb(pParamSpec);
-      std::string strDocs = (pchBlurb) ? pchBlurb : "";
-      // Quick hack to get rid of nested double quotes:
-      std::replace(strDocs.begin(), strDocs.end(), '"', '\'');
-
-      strResult += "(define-property " + strName + "\n";
-      strResult += "  (of-object \"" + strObjectName + "\")\n";
-      strResult += "  (prop-type \"" + strTypeName + "\")\n";
-      strResult += "  (docs \"" + strDocs + "\")\n";
-
-      //Flags:
-      GParamFlags flags = pParamSpec->flags;
-      bool bReadable = (flags & G_PARAM_READABLE) == G_PARAM_READABLE;
-      bool bWritable = (flags & G_PARAM_WRITABLE) == G_PARAM_WRITABLE;
-      bool bConstructOnly = (flags & G_PARAM_CONSTRUCT_ONLY) == G_PARAM_CONSTRUCT_ONLY;
-
-      //#t and #f aren't documented, but I guess that it's correct based on the example in the .defs spec.
-      const std::string strTrue = "#t";
-      const std::string strFalse = "#f";
-
-      strResult += "  (readable " + (bReadable ? strTrue : strFalse) + ")\n";
-      strResult += "  (writable " + (bWritable ? strTrue : strFalse) + ")\n";
-      strResult += "  (construct-only " + (bConstructOnly ? strTrue : strFalse) + ")\n";
-
-      strResult += ")\n\n"; //close (define-property           
+      strResult += get_property_with_node_name(pParamSpec, strObjectName, "define-property");
     }
   }
 
diff --git a/tools/extra_defs_gen/generate_extra_defs.h b/tools/extra_defs_gen/generate_extra_defs.h
index 4866ac0..1283c2d 100644
--- a/tools/extra_defs_gen/generate_extra_defs.h
+++ b/tools/extra_defs_gen/generate_extra_defs.h
@@ -39,6 +39,9 @@ bool gtype_is_a_pointer(GType gtype);
 std::string get_defs(GType gtype,
                 GTypeIsAPointerFunc is_a_pointer_func = gtype_is_a_pointer);
 
+std::string get_property_with_node_name(GParamSpec* pParamSpec,
+                const std::string& strObjectName, const std::string& strNodeName);
+
 std::string get_properties(GType gtype);
 
 std::string get_type_name(GType gtype,
diff --git a/tools/pm/GtkDefs.pm b/tools/pm/GtkDefs.pm
index d9e4532..5fdef5a 100644
--- a/tools/pm/GtkDefs.pm
+++ b/tools/pm/GtkDefs.pm
@@ -34,6 +34,7 @@ use FunctionBase;
 #    @ get_methods()
 #    @ get_signals()
 #    @ get_properties()
+#    @ get_child_properties()
 #    @ get_unwrapped()
 #
 #    $ lookup_enum(c_type)
@@ -43,6 +44,7 @@ use FunctionBase;
 #    $ lookup_method(c_name)
 #    $ lookup_function(c_name)
 #    $ lookup_property(object, c_name)
+#    $ lookup_child_property(object, c_name)
 #    $ lookup_signal(object, c_name)
 #
 
@@ -75,6 +77,7 @@ use warnings;
 %GtkDefs::methods = (); #GtkDefs::Function
 %GtkDefs::signals = (); #GtkDefs::Signal
 %GtkDefs::properties = (); #Property
+%GtkDefs::child_properties = (); #Property
 
 @GtkDefs::read = ();
 @GtkDefs::file = ();
@@ -152,6 +155,8 @@ sub read_defs($$;$)
     { on_method($token); }
     elsif ($token =~ /^\(define-property.*\)$/)
     { on_property($token); }
+    elsif ($token =~ /^\(define-child-property.*\)$/)
+    { on_child_property($token); }
     elsif ($token =~ /^\(define-signal.*\)$/)
     { on_signal($token);  }
     elsif ($token =~ /^\(define-vfunc.*\)$/)
@@ -334,6 +339,12 @@ sub on_property($)
   $GtkDefs::properties{"$$thing{class}::$$thing{name}"} = $thing;
 }
 
+sub on_child_property($)
+{
+  my $thing = Property::new(shift(@_));
+  $GtkDefs::child_properties{"$$thing{class}::$$thing{name}"} = $thing;
+}
+
 sub on_signal($)
 {
   my $thing = GtkDefs::Signal::new(shift(@_));
@@ -365,6 +376,11 @@ sub get_properties
   return sort {$$a{name} cmp $$b{name}} values %GtkDefs::properties;
 }
 
+sub get_child_properties
+{
+  return sort {$$a{name} cmp $$b{name}} values %GtkDefs::child_properties;
+}
+
 sub get_marked
 {
   no warnings;
@@ -380,6 +396,7 @@ sub get_unwrapped
   push @targets,grep {$$_{entity_type} eq "method" && $$_{mark}==1} values %GtkDefs::methods;
   push @targets,grep {$$_{mark}==1} values %GtkDefs::signals;
   push @targets,grep {$$_{mark}==1} values %GtkDefs::properties;
+  push @targets,grep {$$_{mark}==1} values %GtkDefs::child_properties;
 
   # find the classes which used them.
   my @classes = unique(map { $$_{class} } @targets);
@@ -412,10 +429,12 @@ sub get_unwrapped
     if ($detailed)
     {
       push @unwrapped, grep {$$_{class} eq $class && $$_{mark}==0 && not exists $GtkDefs::properties{$parent 
. '::' . $_->{name}}} values %GtkDefs::properties;
+      push @unwrapped, grep {$$_{class} eq $class && $$_{mark}==0 && not exists 
$GtkDefs::child_properties{$parent . '::' . $_->{name}}} values %GtkDefs::child_properties;
     }
     else
     {
       push @unwrapped, grep {$$_{class} eq $class && $$_{mark}==0} values %GtkDefs::properties;
+      push @unwrapped, grep {$$_{class} eq $class && $$_{mark}==0} values %GtkDefs::child_properties;
     }
 
     push @unwrapped, grep {$$_{class} eq $class && $$_{mark}==0} values %GtkDefs::methods;
@@ -474,6 +493,18 @@ sub lookup_property($$)
   return $obj;
 }
 
+# $objChildProperty lookup_child_property($name, $parent_object_name)
+sub lookup_child_property($$)
+{
+  no warnings;
+  my ($parent_object_name, $name) = @_;
+  $name =~ s/-/_/g;
+  my $obj = $GtkDefs::child_properties{"${parent_object_name}::${name}"};
+  return 0 if ($obj eq "");
+  $$obj{mark} = 1;
+  return $obj;
+}
+
 sub lookup_method_dont_mark($)
 {
   no warnings;
diff --git a/tools/pm/Output.pm b/tools/pm/Output.pm
index 975ba75..1a00d66 100644
--- a/tools/pm/Output.pm
+++ b/tools/pm/Output.pm
@@ -763,89 +763,115 @@ sub output_wrap_gerror($$$$$$$)
   $self->append($str);
 }
 
-# _PROPERTY_PROXY(name, cpp_type)
-# void output_wrap_property($filename, $line_num, $name, $cpp_type, $deprecated, $deprecation_docs)
-sub output_wrap_property($$$$$$$$)
+# _PROPERTY_PROXY(name, cpp_type) and _CHILD_PROPERTY_PROXY(name, cpp_type)
+# void output_wrap_any_property($filename, $line_num, $name, $cpp_type, $c_class, $deprecated, 
$deprecation_docs, $objProperty, $proxy_macro)
+sub output_wrap_any_property($$$$$$$$$$)
 {
-  my ($self, $filename, $line_num, $name, $cpp_type, $c_class, $deprecated, $deprecation_docs) = @_;
+  my ($self, $filename, $line_num, $name, $cpp_type, $c_class, $deprecated, $deprecation_docs, $objProperty, 
$proxy_macro) = @_;
 
   my $objDefsParser = $$self{objDefsParser};
 
-  my $objProperty = GtkDefs::lookup_property($c_class, $name);
-  if($objProperty eq 0) #If the lookup failed:
-  {
-    $self->output_wrap_failed($name, "property defs lookup failed.");
-  }
-  else
-  {
-    # We use a suffix to specify a particular Glib::PropertyProxy* class.
-    my $proxy_suffix = "";
+  # We use a suffix to specify a particular Glib::PropertyProxy* class.
+  my $proxy_suffix = "";
 
-    # Read/Write:
-    if($objProperty->get_construct_only() eq 1)
-    {
-      # construct-only functions can be read, but not written.
-      $proxy_suffix = "_ReadOnly";
+  # Read/Write:
+  if($objProperty->get_construct_only() eq 1)
+  {
+    # construct-only functions can be read, but not written.
+    $proxy_suffix = "_ReadOnly";
 
-      if($objProperty->get_readable() ne 1)
-      {
-        $self->output_wrap_failed($name, "attempt to wrap write-only and construct-only property.");
-        return;
-      }
-    }
-    elsif($objProperty->get_readable() ne 1)
-    {
-      $proxy_suffix = "_WriteOnly";
-    }
-    elsif($objProperty->get_writable() ne 1)
+    if($objProperty->get_readable() ne 1)
     {
-       $proxy_suffix = "_ReadOnly";
+      $self->output_wrap_failed($name, "attempt to wrap write-only and construct-only property.");
+      return;
     }
+  }
+  elsif($objProperty->get_readable() ne 1)
+  {
+    $proxy_suffix = "_WriteOnly";
+  }
+  elsif($objProperty->get_writable() ne 1)
+  {
+    $proxy_suffix = "_ReadOnly";
+  }
 
-    # Convert - to _ so we can use it in C++ method and variable names:
-    my $name_underscored = $name;
-    $name_underscored =~ tr/-/_/;
+  # Convert - to _ so we can use it in C++ method and variable names:
+  my $name_underscored = $name;
+  $name_underscored =~ tr/-/_/;
 
-    # Get the property documentation, if any, and add m4 quotes.
-    my $documentation = $objProperty->get_docs($deprecation_docs);
-    add_m4_quotes(\$documentation) if ($documentation ne "");
+  # Get the property documentation, if any, and add m4 quotes.
+  my $documentation = $objProperty->get_docs($deprecation_docs);
+  add_m4_quotes(\$documentation) if ($documentation ne "");
 
-    #Declaration:
-    if($deprecated ne "")
-    {
-      $self->append("\n_DEPRECATE_IFDEF_START\n");
-    }
+  #Declaration:
+  if($deprecated ne "")
+  {
+    $self->append("\n_DEPRECATE_IFDEF_START\n");
+  }
+
+  my $str = sprintf("$proxy_macro(%s,%s,%s,%s,%s,`%s')dnl\n",
+    $name,
+    $name_underscored,
+    $cpp_type,
+    $proxy_suffix,
+    $deprecated,
+    $documentation
+  );
+  $self->append($str);
+  $self->append("\n");
 
-    my $str = sprintf("_PROPERTY_PROXY(%s,%s,%s,%s,%s,`%s')dnl\n",
+  # If the property is not already read-only, and the property can be read,
+  # then add a second const accessor for a read-only propertyproxy:
+  if( ($proxy_suffix ne "_ReadOnly") && ($objProperty->get_readable()) )
+  {
+    my $str = sprintf("$proxy_macro(%s,%s,%s,%s,%s,`%s')dnl\n",
       $name,
       $name_underscored,
       $cpp_type,
-      $proxy_suffix,
+      "_ReadOnly",
       $deprecated,
       $documentation
     );
     $self->append($str);
-    $self->append("\n");
+  }
 
-    # If the property is not already read-only, and the property can be read,
-    # then add a second const accessor for a read-only propertyproxy:
-    if( ($proxy_suffix ne "_ReadOnly") && ($objProperty->get_readable()) )
-    {
-      my $str = sprintf("_PROPERTY_PROXY(%s,%s,%s,%s,%s,`%s')dnl\n",
-        $name,
-        $name_underscored,
-        $cpp_type,
-        "_ReadOnly",
-        $deprecated,
-        $documentation
-      );
-      $self->append($str);
-    }
+  if($deprecated ne "")
+  {
+    $self->append("\n_DEPRECATE_IFDEF_END");
+  }
+}
 
-    if($deprecated ne "")
-    {
-      $self->append("\n_DEPRECATE_IFDEF_END");
-    }
+# _PROPERTY_PROXY(name, cpp_type)
+# void output_wrap_property($filename, $line_num, $name, $cpp_type, $deprecated, $deprecation_docs)
+sub output_wrap_property($$$$$$$$)
+{
+  my ($self, $filename, $line_num, $name, $cpp_type, $c_class, $deprecated, $deprecation_docs) = @_;
+
+  my $objProperty = GtkDefs::lookup_property($c_class, $name);
+  if($objProperty eq 0) #If the lookup failed:
+  {
+    $self->output_wrap_failed($name, "property defs lookup failed.");
+  }
+  else
+  {
+    $self->output_wrap_any_property($filename, $line_num, $name, $cpp_type, $c_class, $deprecated, 
$deprecation_docs, $objProperty, "_PROPERTY_PROXY");
+  }
+}
+
+# _CHILD_PROPERTY_PROXY(name, cpp_type)
+# void output_wrap_child_property($filename, $line_num, $name, $cpp_type, $deprecated, $deprecation_docs)
+sub output_wrap_child_property($$$$$$$$)
+{
+  my ($self, $filename, $line_num, $name, $cpp_type, $c_class, $deprecated, $deprecation_docs) = @_;
+
+  my $objChildProperty = GtkDefs::lookup_child_property($c_class, $name);
+  if($objChildProperty eq 0) #If the lookup failed:
+  {
+    $self->output_wrap_failed($name, "child property defs lookup failed.");
+  }
+  else
+  {
+    $self->output_wrap_any_property($filename, $line_num, $name, $cpp_type, $c_class, $deprecated, 
$deprecation_docs, $objChildProperty, "_CHILD_PROPERTY_PROXY");
   }
 }
 
diff --git a/tools/pm/Property.pm b/tools/pm/Property.pm
index 03d67b4..f89140e 100644
--- a/tools/pm/Property.pm
+++ b/tools/pm/Property.pm
@@ -40,7 +40,7 @@ sub new
   $def=~s/\)$//;
   # snarf down the fields
   $$self{mark} = 0;
-  $$self{name} = $1                     if ($def =~ s/^define-property (\S+)//);
+  $$self{name} = $2                     if ($def =~ s/(^define-property|^define-child-property) (\S+)//);
   $$self{class} = $1                    if ($def =~ s/\(of-object "(\S+)"\)//);
   $$self{type} = $1                     if ($def =~ s/\(prop-type "(\S+)"\)//);
   $$self{readable} = ($1 eq "#t")       if ($def =~ s/\(readable (\S+)\)//);
diff --git a/tools/pm/WrapParser.pm b/tools/pm/WrapParser.pm
index f7df4ba..1ef5cbc 100644
--- a/tools/pm/WrapParser.pm
+++ b/tools/pm/WrapParser.pm
@@ -116,6 +116,7 @@ sub parse_and_build_output($)
     if ($token eq "_WRAP_CORBA_METHOD")     { $self->on_wrap_corba_method(); next;} #Used in libbonobo*mm.
     if ($token eq "_WRAP_SIGNAL") { $self->on_wrap_signal(); next;}
     if ($token eq "_WRAP_PROPERTY") { $self->on_wrap_property(); next;}
+    if ($token eq "_WRAP_CHILD_PROPERTY") { $self->on_wrap_child_property(); next;}
     if ($token eq "_WRAP_VFUNC") { $self->on_wrap_vfunc(); next;}
     if ($token eq "_WRAP_CTOR")   { $self->on_wrap_ctor(); next;}
     if ($token eq "_WRAP_CREATE") { $self->on_wrap_create(); next;}
@@ -1401,12 +1402,9 @@ sub on_wrap_gerror($)
       $$self{filename}, $$self{line_num}, $cpp_type, $c_enum, $domain, @args);
 }
 
-sub on_wrap_property($)
+sub on_wrap_any_property($)
 {
   my ($self) = @_;
-  my $objOutputter = $$self{objOutputter};
-
-  return unless ($self->check_for_eof());
 
   my $str = $self->extract_bracketed_text();
   my @args = string_split_commas($str);
@@ -1446,10 +1444,32 @@ sub on_wrap_property($)
     }
   }
 
+  return ($filename, $line_num, $argPropertyName, $argCppType, $argDeprecated, $deprecation_docs);
+}
+
+sub on_wrap_property($)
+{
+  my ($self) = @_;
+  my $objOutputter = $$self{objOutputter};
+
+  return unless ($self->check_for_eof());
+
+  my ($filename, $line_num, $argPropertyName, $argCppType, $argDeprecated, $deprecation_docs) = 
$self->on_wrap_any_property();
 
   $objOutputter->output_wrap_property($filename, $line_num, $argPropertyName, $argCppType, $$self{c_class}, 
$argDeprecated, $deprecation_docs);
 }
 
+sub on_wrap_child_property($)
+{
+  my ($self) = @_;
+  my $objOutputter = $$self{objOutputter};
+
+  return unless ($self->check_for_eof());
+
+  my ($filename, $line_num, $argPropertyName, $argCppType, $argDeprecated, $deprecation_docs) = 
$self->on_wrap_any_property();
+
+  $objOutputter->output_wrap_child_property($filename, $line_num, $argPropertyName, $argCppType, 
$$self{c_class}, $argDeprecated, $deprecation_docs);
+}
 
 sub output_wrap_check($$$$$$)
 {


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