diff options
Diffstat (limited to 'glib/glibmm/propertyproxy_base.cc')
-rw-r--r-- | glib/glibmm/propertyproxy_base.cc | 159 |
1 files changed, 159 insertions, 0 deletions
diff --git a/glib/glibmm/propertyproxy_base.cc b/glib/glibmm/propertyproxy_base.cc new file mode 100644 index 00000000..177ab6e8 --- /dev/null +++ b/glib/glibmm/propertyproxy_base.cc @@ -0,0 +1,159 @@ +// -*- c++ -*- +/* $Id$ */ + +/* propertyproxy_base.h + * + * Copyright 2002 The gtkmm Development Team + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library 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 + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library 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/propertyproxy_base.h> +#include <glibmm/signalproxy_connectionnode.h> +#include <glibmm/object.h> +#include <glibmm/private/object_p.h> + +namespace Glib +{ + +/** PropertyProxyConnectionNode is a SigC::ConnectionNode for use with SignalProxyProperty. + * It's like ProxyConnectionNode, but it contains the property name too. + */ +class PropertyProxyConnectionNode : public SignalProxyConnectionNode +{ +public: + friend class SignalProxyProperty; + + PropertyProxyConnectionNode(SigC::SlotNode* slot_data, GObject* gobject, const gchar* property_name); + virtual ~PropertyProxyConnectionNode(); + +protected: + //This will be examined in the callback. + //Should be a static string literal. + const gchar* property_name_; +}; + +PropertyProxyConnectionNode::PropertyProxyConnectionNode(SigC::SlotNode* slot_data, GObject* gobject, const gchar* property_name) +: SignalProxyConnectionNode(slot_data, gobject), + property_name_(property_name) +{ +} + +PropertyProxyConnectionNode::~PropertyProxyConnectionNode() +{ +} + +//SignalProxyProperty implementation: + +SignalProxyProperty::SignalProxyProperty(Glib::ObjectBase* obj, const gchar* property_name) +: SignalProxyBase(obj), + property_name_(property_name) +{ +} + +SignalProxyProperty::~SignalProxyProperty() +{ +} + +SigC::Connection SignalProxyProperty::connect(const SlotType& sl) +{ + // create a proxy to hold our connection info + PropertyProxyConnectionNode* pConnectionNode = new PropertyProxyConnectionNode( (SigC::SlotNode*)(sl.impl()), obj_->gobj(), property_name_ ); + + // gtk+ will hold a reference to this object + pConnectionNode->reference(); + + // connect it to gtk+ + // pConnectionNode will be passed as the data argument to the callback. + // The callback will then call the virtual Object::property_change_notify() method, + // which will contain a switch/case statement which will examine the property name. + pConnectionNode->connection_id_ = g_signal_connect_data(obj_->gobj(), + "notify", (GCallback)(&callback), pConnectionNode, + &PropertyProxyConnectionNode::destroy_notify_handler, + G_CONNECT_AFTER); + + return SigC::Connection(pConnectionNode); +} + +void SignalProxyProperty::callback(GObject*, GParamSpec* pspec, gpointer data) //static +{ + if(pspec && data) + { + //Get the name of the property that has changed: + const char* property_name_changed = pspec->name; + + //Get the name of the property that we are waiting for: + PropertyProxyConnectionNode* conn = static_cast<PropertyProxyConnectionNode*>(data); + const char* property_name_monitored = conn->property_name_; + + //If it's the correct property, then call the signal handler: + if(strcmp(property_name_changed, property_name_monitored) == 0) + { + if(SigC::SlotNode *const slot = data_to_slot(data)) + (*(SlotType::Proxy)(slot->proxy_))(slot); + } + } +} + + +//PropertyProxy_Base implementation: + +PropertyProxy_Base::PropertyProxy_Base(Object* obj, const char* property_name) +: + obj_ (obj), + property_name_ (property_name) +{} + +PropertyProxy_Base::PropertyProxy_Base(const PropertyProxy_Base& other) +: + obj_ (other.obj_), + property_name_ (other.property_name_) +{} + +SignalProxyProperty PropertyProxy_Base::signal_changed() +{ + return SignalProxyProperty(obj_, property_name_); +} + +void PropertyProxy_Base::set_property_(const Glib::ValueBase& value) +{ + g_object_set_property(obj_->gobj(), property_name_, value.gobj()); +} + +void PropertyProxy_Base::get_property_(Glib::ValueBase& value) const +{ + g_object_get_property(obj_->gobj(), property_name_, value.gobj()); +} + +void PropertyProxy_Base::reset_property_() +{ + // Get information about the parameter: + const GParamSpec *const pParamSpec = + g_object_class_find_property(G_OBJECT_GET_CLASS(obj_->gobj()), property_name_); + + g_return_if_fail(pParamSpec != 0); + + Glib::ValueBase value; + value.init(G_PARAM_SPEC_VALUE_TYPE(pParamSpec)); + + // An explicit reset is not needed, because ValueBase:init() + // has already initialized it to the default value for this type. + // value.reset(); + + g_object_set_property(obj_->gobj(), property_name_, value.gobj()); +} + +} // namespace Glib + |