+2.41.2 (unstable):
+
+Gio:
+* Menu: Allow detailed_action == null
+ (Kjell Ahlstedt) Bug #733203 (Hubert Figuiere)
+* Add Permission and SimplePermission.
+ (Juan R. García Blanco) Bug #732436
+
+Glib:
+* Make custom interface properties instance data.
+ (Kjell Ahlstedt) Bug #732746
+* PropertyBase: Use g_object_notify_by_pspec() instead of g_object_notify()
+ (Povilas Kanapickas) Bug #731484
+
+gmmproc:
+* Add support for GtkContainer child properties.
+ (Juan R. García Blanco)
+* _WRAP_METHOD: Allow multi-word parameter types such as unsigned int.
+ (Kjell Ahlstedt)
+
+
2.41.1 (unstable):
Gio:
## 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/>.
-AC_INIT([glibmm], [2.41.1],
+AC_INIT([glibmm], [2.41.2],
[http://bugzilla.gnome.org/enter_bug.cgi?product=glibmm],
[glibmm], [http://www.gtkmm.org/])
AC_PREREQ([2.59])
#include <giomm/networkservice.h>
#include <giomm/notification.h>
#include <giomm/outputstream.h>
+#include <giomm/permission.h>
#include <giomm/pollableinputstream.h>
#include <giomm/pollableoutputstream.h>
#include <giomm/proxy.h>
#include <giomm/settings.h>
#include <giomm/simpleaction.h>
#include <giomm/simpleactiongroup.h>
+#include <giomm/simplepermission.h>
#include <giomm/socket.h>
#include <giomm/socketaddress.h>
#include <giomm/socketaddressenumerator.h>
networkservice.hg \
notification.hg \
outputstream.hg \
+ permission.hg \
pollableinputstream.hg \
pollableoutputstream.hg \
proxy.hg \
settings.hg \
simpleaction.hg \
simpleactiongroup.hg \
+ simplepermission.hg \
socket.hg \
socketaddress.hg \
socketaddressenumerator.hg \
;; From GNotification
+;; From GPermission
+
+(define-property allowed
+ (of-object "GPermission")
+ (prop-type "GParamBoolean")
+ (docs "If the caller is allowed to perform the action")
+ (readable #t)
+ (writable #f)
+ (construct-only #f)
+)
+
+(define-property can-acquire
+ (of-object "GPermission")
+ (prop-type "GParamBoolean")
+ (docs "If calling g_permission_acquire() makes sense")
+ (readable #t)
+ (writable #f)
+ (construct-only #f)
+)
+
+(define-property can-release
+ (of-object "GPermission")
+ (prop-type "GParamBoolean")
+ (docs "If calling g_permission_release() makes sense")
+ (readable #t)
+ (writable #f)
+ (construct-only #f)
+)
+
;; From GPropertyAction
(define-property name
'("GMount*" "mount")
)
)
+
+; GPermission
+
+(define-vfunc acquire
+ (of-object "GPermission")
+ (return-type "gboolean")
+ (parameters
+ '("GCancellable*" "cancellable")
+ '("GError**" "error")
+ )
+)
+
+(define-vfunc acquire_async
+ (of-object "GPermission")
+ (return-type "void")
+ (parameters
+ '("GCancellable*" "cancellable")
+ '("GAsyncReadyCallback" "callback")
+ '("gpointer" "user_data")
+ )
+)
+
+(define-vfunc acquire_finish
+ (of-object "GPermission")
+ (return-type "gboolean")
+ (parameters
+ '("GAsyncResult*" "result")
+ '("GError**" "error")
+ )
+)
+
+(define-vfunc release
+ (of-object "GPermission")
+ (return-type "gboolean")
+ (parameters
+ '("GCancellable*" "cancellable")
+ '("GError**" "error")
+ )
+)
+
+(define-vfunc release_async
+ (of-object "GPermission")
+ (return-type "void")
+ (parameters
+ '("GCancellable*" "cancellable")
+ '("GAsyncReadyCallback" "callback")
+ '("gpointer" "user_data")
+ )
+)
+
+(define-vfunc release_finish
+ (of-object "GPermission")
+ (return-type "gboolean")
+ (parameters
+ '("GAsyncResult*" "result")
+ '("GError**" "error")
+ )
+)
_WRAP_METHOD(void remove(int position), g_menu_remove)
_WRAP_METHOD(void remove_all(), g_menu_remove_all)
-//TODO: Allow label to be null. But when would that be useful?
+// The glib docs says that label can be null in all insert/prepend/append functions.
+// But except in the xxx_section() functions, a null label results in a critical message,
+// and does not seem useful. See https://bugzilla.gnome.org/show_bug.cgi?id=733203
//We don't return the MenuItem* because the C API can't give us something modifiable: See https://bugzilla.gnome.org/show_bug.cgi?id=708906
- _WRAP_METHOD(void insert(int position, const Glib::ustring& label, const Glib::ustring& detailed_action = Glib::ustring()), g_menu_insert)
- _WRAP_METHOD(void prepend(const Glib::ustring& label, const Glib::ustring& detailed_action = Glib::ustring()), g_menu_prepend)
- _WRAP_METHOD(void append(const Glib::ustring& label, const Glib::ustring& detailed_action = Glib::ustring()), g_menu_append)
+ _WRAP_METHOD(void insert(int position, const Glib::ustring& label, const Glib::ustring& detailed_action{?}), g_menu_insert)
+ _WRAP_METHOD(void prepend(const Glib::ustring& label, const Glib::ustring& detailed_action{?}), g_menu_prepend)
+ _WRAP_METHOD(void append(const Glib::ustring& label, const Glib::ustring& detailed_action{?}), g_menu_append)
_WRAP_METHOD(void insert_section(int position, const Glib::ustring& label{?}, const Glib::RefPtr<MenuModel>& section), g_menu_insert_section)
_WRAP_METHOD(void prepend_section(const Glib::ustring& label{?}, const Glib::RefPtr<MenuModel>& section), g_menu_prepend_section)
--- /dev/null
+/* Copyright (C) 2014 The giomm Development Team
+ *
+ * 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, write to the Free
+ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include <gio/gio.h>
+#include "slot_async.h"
+
+
+namespace Gio
+{
+} // namespace Gio
--- /dev/null
+/* Copyright (C) 2014 The giomm Development Team
+ *
+ * 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, write to the Free
+ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include <glibmm/object.h>
+#include <giomm/cancellable.h>
+#include <giomm/asyncresult.h>
+
+_DEFS(giomm,gio)
+_PINCLUDE(glibmm/private/object_p.h)
+_PINCLUDE(gio/gio.h)
+
+namespace Gio
+{
+
+/** An object representing the permission to perform a certain action.
+ *
+ * A Permission represents the status of the caller's permission to
+ * perform a certain action.
+ *
+ * You can query if the action is currently allowed and if it is
+ * possible to acquire the permission so that the action will be allowed
+ * in the future.
+ *
+ * There is also an API to actually acquire the permission and one to
+ * release it.
+ *
+ * As an example, a Permission might represent the ability for the
+ * user to write to a Settings object. This Permission object could
+ * then be used to decide if it is appropriate to show a "Click here to
+ * unlock" button in a dialog and to provide the mechanism to invoke
+ * when that button is clicked.
+ *
+ * @newin{2,42}
+ */
+class Permission : public Glib::Object
+{
+ _CLASS_GOBJECT(Permission, GPermission, G_PERMISSION, Glib::Object, GObject)
+
+public:
+
+ _WRAP_METHOD(bool acquire(const Glib::RefPtr<Cancellable>& cancellable{?}), g_permission_acquire, errthrow)
+ _WRAP_METHOD(void acquire_async(const SlotAsyncReady& slot{callback}, const Glib::RefPtr<Cancellable>& cancellable{.?}), g_permission_acquire_async, slot_name slot, slot_callback SignalProxy_async_callback)
+ _WRAP_METHOD(bool acquire_finish(const Glib::RefPtr<AsyncResult>& result), g_permission_acquire_finish, errthrow)
+
+ _WRAP_METHOD(bool release(const Glib::RefPtr<Cancellable>& cancellable{?}), g_permission_release, errthrow)
+ _WRAP_METHOD(void release_async(const SlotAsyncReady& slot{callback}, const Glib::RefPtr<Cancellable>& cancellable{.?}), g_permission_release_async, slot_name slot, slot_callback SignalProxy_async_callback)
+ _WRAP_METHOD(bool release_finish(const Glib::RefPtr<AsyncResult>& result), g_permission_release_finish, errthrow)
+
+ _WRAP_METHOD(bool get_allowed() const, g_permission_get_allowed)
+ _WRAP_METHOD(bool get_can_acquire() const, g_permission_get_can_acquire)
+ _WRAP_METHOD(bool get_can_release() const, g_permission_get_can_release)
+
+ _WRAP_PROPERTY("allowed", bool)
+ _WRAP_PROPERTY("can-acquire", bool)
+ _WRAP_PROPERTY("can-release", bool)
+
+protected:
+
+ _CTOR_DEFAULT
+
+// A copy is needed for vfuncs, i.e. Glib::wrap($3, true)
+#m4 _CONVERSION(`GAsyncResult*',`const Glib::RefPtr<AsyncResult>&',`Glib::wrap($3, true)')
+#m4 _CONVERSION(`GCancellable*',`const Glib::RefPtr<Cancellable>&',`Glib::wrap($3, true)')
+
+ _WRAP_VFUNC(bool acquire(const Glib::RefPtr<Cancellable>& cancellable), acquire, errthrow)
+ _WRAP_VFUNC(void acquire_async(const SlotAsyncReady& slot{callback}, const Glib::RefPtr<Cancellable>& cancellable{.}), acquire_async, slot_name slot, slot_callback SignalProxy_async_callback)
+ _WRAP_VFUNC(bool acquire_finish(const Glib::RefPtr<AsyncResult>& result), acquire_finish, errthrow)
+
+ _WRAP_VFUNC(bool release(const Glib::RefPtr<Cancellable>& cancellable), release, errthrow)
+ _WRAP_VFUNC(void release_async(const SlotAsyncReady& slot{callback}, const Glib::RefPtr<Cancellable>& cancellable{.}), release_async, slot_name slot, slot_callback SignalProxy_async_callback)
+ _WRAP_VFUNC(bool release_finish(const Glib::RefPtr<AsyncResult>& result), release_finish, errthrow)
+
+ // You should never call this function except from a Gio::Permission implementation.
+ _WRAP_METHOD(void impl_update(bool allowed, bool can_acquire, bool can_release), g_permission_impl_update)
+};
+
+} // namespace Gio
--- /dev/null
+/* Copyright (C) 2014 The gtkmm Development Team
+ *
+ * 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, write to the Free
+ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include <gio/gio.h>
+
+
+namespace Gio
+{
+} // namespace Gio
--- /dev/null
+/* Copyright (C) 2014 The giomm Development Team
+ *
+ * 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, write to the Free
+ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include <giomm/permission.h>
+
+_DEFS(giomm,gio)
+_PINCLUDE(giomm/private/permission_p.h)
+
+namespace Gio
+{
+
+/** A Permission that doesn't change value.
+ *
+ * SimplePermission is a trivial implementation of Permission that
+ * represents a permission that is either always or never allowed. The
+ * value is given at construction and doesn't change.
+ *
+ * Calling Permission::acquire() or Permission::release() will result
+ * in errors.
+ */
+class SimplePermission : public Permission
+{
+ _CLASS_GOBJECT(SimplePermission, GSimplePermission, G_SIMPLE_PERMISSION, Gio::Permission, GPermission)
+
+protected:
+
+ _WRAP_CTOR(SimplePermission(bool allowed), g_simple_permission_new)
+
+public:
+
+ _WRAP_CREATE(bool allowed)
+
+ // SimplePermission has no properties nor signals.
+};
+
+} // namespace Gio
}
// Initialize the static quark to store/get custom type properties.
-GQuark Class::properties_quark = g_quark_from_string("gtkmm_CustomObject_properties");
+GQuark Class::iface_properties_quark = g_quark_from_string("gtkmm_CustomObject_iface_properties");
// static
void Class::custom_class_base_finalize_function(void* g_class)
{
const GType gtype = G_TYPE_FROM_CLASS(g_class);
- // Free the data related to the properties for the custom type, if any.
- properties_type* props = static_cast<properties_type*>(g_type_get_qdata(gtype, properties_quark));
+ // Free the data related to the interface properties for the custom type, if any.
+ iface_properties_type* props = static_cast<iface_properties_type*>(
+ g_type_get_qdata(gtype, iface_properties_quark));
if(props)
{
- for(properties_type::size_type i = 0; i < props->size(); i++)
+ for(iface_properties_type::size_type i = 0; i < props->size(); i++)
{
g_value_unset((*props)[i]);
g_free((*props)[i]);
// Override the properties of implemented interfaces, if any.
const GType object_type = G_TYPE_FROM_CLASS(g_class);
- Class::properties_type* props = static_cast<Class::properties_type*>(
- g_type_get_qdata(object_type, Class::properties_quark));
+ Class::iface_properties_type* props = static_cast<Class::iface_properties_type*>(
+ g_type_get_qdata(object_type, Class::iface_properties_quark));
if (!props)
{
- props = new Class::properties_type();
- g_type_set_qdata(object_type, Class::properties_quark, props);
+ props = new Class::iface_properties_type();
+ g_type_set_qdata(object_type, Class::iface_properties_quark, props);
}
guint n_interfaces = 0;
const gchar* prop_name = g_param_spec_get_name(iface_props[p]);
// Override only properties which have not been overridden in a base class.
+ // Store the default values belonging to the class.
+ // They are copied to an object in custom_set_property_callback() in property.cc.
if (!g_object_class_find_property(gobject_class, prop_name))
{
GValue* g_value = g_new0(GValue, 1);
g_value_init(g_value, iface_props[p]->value_type);
+ g_param_value_set_default(iface_props[p], g_value);
props->push_back(g_value);
g_object_class_override_property(gobject_class, props->size(), prop_name);
#include <glib-object.h>
#include <glibmmconfig.h> //Include this here so that the /private/*.h classes have access to GLIBMM_VFUNCS_ENABLED
-#include <vector> //For properties that custom types might override.
+#include <vector> //For interface properties that custom types might override.
#ifndef DOXYGEN_SHOULD_SKIP_THIS
public:
#ifndef DOXYGEN_SHOULD_SKIP_THIS
- // The type that holds the values of the properties of custom types.
- typedef std::vector<GValue*> properties_type;
- // The quark used for storing/getting the properties of custom types.
- static GQuark properties_quark;
+ // The type that holds the values of the interface properties of custom types.
+ typedef std::vector<GValue*> iface_properties_type;
+ // The quark used for storing/getting the interface properties of custom types.
+ static GQuark iface_properties_quark;
#endif
};
// Override the properties of the derived interface, if any.
const GType custom_type = G_OBJECT_CLASS_TYPE(instance_class);
- Class::properties_type* props = static_cast<Class::properties_type*>(
- g_type_get_qdata(custom_type, Class::properties_quark));
+ Class::iface_properties_type* props = static_cast<Class::iface_properties_type*>(
+ g_type_get_qdata(custom_type, Class::iface_properties_quark));
if(!props)
{
- props = new Class::properties_type();
- g_type_set_qdata(custom_type, Class::properties_quark, props);
+ props = new Class::iface_properties_type();
+ g_type_set_qdata(custom_type, Class::iface_properties_quark, props);
}
const guint n_existing_props = props->size();
return *static_cast<Glib::PropertyBase*>(prop_ptr);
}
+// Delete the interface property values when an object of a custom type is finalized.
+void destroy_notify_obj_iface_props(void* data)
+{
+ Glib::Class::iface_properties_type* obj_iface_props =
+ static_cast<Glib::Class::iface_properties_type*>(data);
+
+ if (obj_iface_props)
+ {
+ for (Glib::Class::iface_properties_type::size_type i = 0; i < obj_iface_props->size(); i++)
+ {
+ g_value_unset((*obj_iface_props)[i]);
+ g_free((*obj_iface_props)[i]);
+ }
+ delete obj_iface_props;
+ }
+}
+
} // anonymous namespace
GType custom_type = G_OBJECT_TYPE(object);
- Class::properties_type* props = static_cast<Class::properties_type*>(g_type_get_qdata(custom_type, Class::properties_quark));
- Class::properties_type::size_type props_size = 0;
+ Class::iface_properties_type* iface_props = static_cast<Class::iface_properties_type*>(
+ g_type_get_qdata(custom_type, Class::iface_properties_quark));
+
+ Class::iface_properties_type::size_type iface_props_size = 0;
- if(props) props_size = props->size();
+ if (iface_props)
+ iface_props_size = iface_props->size();
- if(property_id <= props_size)
+ if (property_id <= iface_props_size)
{
- g_value_copy((*props)[property_id - 1], value);
+ // Get the object's property value if there is one, else the class's default value.
+ Class::iface_properties_type* obj_iface_props = static_cast<Class::iface_properties_type*>(
+ g_object_get_qdata(object, Class::iface_properties_quark));
+ if (obj_iface_props)
+ g_value_copy((*obj_iface_props)[property_id - 1], value);
+ else
+ g_value_copy((*iface_props)[property_id - 1], value);
}
else
{
if(Glib::ObjectBase *const wrapper = Glib::ObjectBase::_get_current_wrapper(object))
{
PropertyBase& property =
- property_from_id(*wrapper, property_id - props_size);
+ property_from_id(*wrapper, property_id - iface_props_size);
if((property.object_ == wrapper) && (property.param_spec_ == param_spec))
g_value_copy(property.value_.gobj(), value);
GType custom_type = G_OBJECT_TYPE(object);
- Class::properties_type* props = static_cast<Class::properties_type*>(g_type_get_qdata(custom_type, Class::properties_quark));
- Class::properties_type::size_type props_size = 0;
+ Class::iface_properties_type* iface_props = static_cast<Class::iface_properties_type*>(
+ g_type_get_qdata(custom_type, Class::iface_properties_quark));
- if(props) props_size = props->size();
+ Class::iface_properties_type::size_type iface_props_size = 0;
- if(property_id <= props_size)
+ if (iface_props)
+ iface_props_size = iface_props->size();
+
+ if (property_id <= iface_props_size)
{
- g_value_copy(value, (*props)[property_id - 1]);
- g_object_notify(object, g_param_spec_get_name(param_spec));
+ // If the object does not have interface property values,
+ // copy the class's default values to the object.
+ Class::iface_properties_type* obj_iface_props = static_cast<Class::iface_properties_type*>(
+ g_object_get_qdata(object, Class::iface_properties_quark));
+ if (!obj_iface_props)
+ {
+ obj_iface_props = new Class::iface_properties_type();
+ g_object_set_qdata_full(object, Class::iface_properties_quark, obj_iface_props,
+ destroy_notify_obj_iface_props);
+ for (Class::iface_properties_type::size_type p = 0; p < iface_props_size; ++p)
+ {
+ GValue* g_value = g_new0(GValue, 1);
+ g_value_init(g_value, G_VALUE_TYPE((*iface_props)[p]));
+ g_value_copy((*iface_props)[p], g_value);
+ obj_iface_props->push_back(g_value);
+ }
+ }
+
+ g_value_copy(value, (*obj_iface_props)[property_id - 1]);
+ g_object_notify_by_pspec(object, param_spec);
}
else
{
if(Glib::ObjectBase *const wrapper = Glib::ObjectBase::_get_current_wrapper(object))
{
PropertyBase& property =
- property_from_id(*wrapper, property_id - props_size);
+ property_from_id(*wrapper, property_id - iface_props_size);
if((property.object_ == wrapper) && (property.param_spec_ == param_spec))
{
g_value_copy(value, property.value_.gobj());
- g_object_notify(object, g_param_spec_get_name(param_spec));
+ g_object_notify_by_pspec(object, param_spec);
}
else
G_OBJECT_WARN_INVALID_PROPERTY_ID(object, property_id, param_spec);
// properties.
GType gtype = G_OBJECT_TYPE(object_->gobj());
- Class::properties_type* props = static_cast<Class::properties_type*>(g_type_get_qdata(gtype, Class::properties_quark));
+ Class::iface_properties_type* iface_props = static_cast<Class::iface_properties_type*>(
+ g_type_get_qdata(gtype, Class::iface_properties_quark));
- Class::properties_type::size_type props_size = 0;
- if(props) props_size = props->size();
+ Class::iface_properties_type::size_type iface_props_size = 0;
+ if (iface_props)
+ iface_props_size = iface_props->size();
- const unsigned int property_id = property_to_id(*object_, *this) + props_size;
+ const unsigned int property_id = property_to_id(*object_, *this) + iface_props_size;
g_object_class_install_property(G_OBJECT_GET_CLASS(object_->gobj()), property_id, param_spec);
void PropertyBase::notify()
{
- g_object_notify(object_->gobj(), g_param_spec_get_name(param_spec_));
+ g_object_notify_by_pspec(object_->gobj(), param_spec_);
}
} // namespace Glib
-
-
<< get_defs(G_TYPE_MOUNT)
<< get_defs(G_TYPE_MOUNT_OPERATION)
<< get_defs(G_TYPE_NOTIFICATION)
+ << get_defs(G_TYPE_PERMISSION)
<< get_defs(G_TYPE_PROPERTY_ACTION)
<< get_defs(G_TYPE_PROXY)
<< get_defs(G_TYPE_PROXY_ADDRESS)
<< get_defs(G_TYPE_NETWORK_ADDRESS)
<< get_defs(G_TYPE_NETWORK_SERVICE)
<< get_defs(G_TYPE_SETTINGS)
+ << get_defs(G_TYPE_SIMPLE_PERMISSION)
<< get_defs(G_TYPE_SOCKET)
<< get_defs(G_TYPE_SOCKET_CLIENT)
<< get_defs(G_TYPE_SOCKET_CONNECTION)
#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.
// 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");
}
}
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,
}
# parses C++ parameter lists.
-# forms a list of types, names, and initial values
-# (we don't currently use values)
+# forms a list of types, names, and default values
sub parse_param($$)
{
my ($self, $line) = @_;
-
my $type = "";
my $name = "";
+ my $name_pos = -1;
my $value = "";
my $id = 0;
my $has_value = 0;
}
elsif ( $_ eq "=" ) #Default value
{
+ $str[$name_pos] = "" if ($name_pos >= 0);
$type = join("", @str); #The type is everything before the = character.
@str = (); #Wipe it so that it will only contain the default value, which comes next.
$has_value = 1;
}
else
{
+ $str[$name_pos] = "" if ($name_pos >= 0);
$type = join("", @str);
}
$value = "";
$has_value = 0;
$name = "";
+ $name_pos = -1;
$flags = 0;
$curr_param++;
next;
}
+ # The last identifier before ',', '=', or '{.*}' is the parameter name.
+ # E.g. int name, unsigned long int name = 42, const unsigned int& name.
+ # The name must be preceded by at least one other identifier (the type).
+ # 'const ' is treated specially, as it can't by itself denote the type.
$id++;
- $name = $_ if ($id == 2);
- push(@str, $_) if ($id == 1);
-
- if ($id > 2)
+ push(@str, $_);
+ if ($id >= 2)
{
- print STDERR "Can't parse $line.\n";
- print STDERR " arg type so far: $type\n";
- print STDERR " arg name so far: $name\n";
- print STDERR " arg default value so far: $value\n";
+ $name = $_;
+ $name_pos = $#str;
}
}
}
else
{
+ $str[$name_pos] = "" if ($name_pos >= 0);
$type = join("", @str);
}
# @ get_methods()
# @ get_signals()
# @ get_properties()
+# @ get_child_properties()
# @ get_unwrapped()
#
# $ lookup_enum(c_type)
# $ lookup_method(c_name)
# $ lookup_function(c_name)
# $ lookup_property(object, c_name)
+# $ lookup_child_property(object, c_name)
# $ lookup_signal(object, c_name)
#
%GtkDefs::methods = (); #GtkDefs::Function
%GtkDefs::signals = (); #GtkDefs::Signal
%GtkDefs::properties = (); #Property
+%GtkDefs::child_properties = (); #Property
@GtkDefs::read = ();
@GtkDefs::file = ();
{ 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.*\)$/)
$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(@_));
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;
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);
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;
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;
$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");
}
}
$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+)\)//);
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;}
$$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);
}
}
+ 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($$$$$$)
{