static gint property_class_comp (gconstpointer a, gconstpointer b) { GladePropertyClass *ca = (GladePropertyClass *)a, *cb = (GladePropertyClass *)b; GParamSpec *pa, *pb; const gchar *name_a, *name_b; pa = glade_property_class_get_pspec (ca); pb = glade_property_class_get_pspec (cb); name_a = glade_property_class_id (ca); name_b = glade_property_class_id (cb); /* Special case for the 'name' property, it *always* comes first. */ if (strcmp (name_a, "name") == 0) return -1; else if (strcmp (name_b, "name") == 0) return 1; /* Properties of the same class are sorted in the same level */ else if (pa->owner_type == pb->owner_type) { gdouble result = glade_property_class_weight (ca) - glade_property_class_weight (cb); /* Avoid cast to int */ if (result < 0.0) return -1; else if (result > 0.0) return 1; else return 0; } /* Group properties by thier class hierarchy */ else { if (g_type_is_a (pa->owner_type, pb->owner_type)) return (glade_property_class_common (ca) || glade_property_class_get_is_packing (ca)) ? 1 : -1; else return (glade_property_class_common (ca) || glade_property_class_get_is_packing (ca)) ? -1 : 1; } }
static gboolean glade_property_verify (GladeProperty * property, const GValue * value) { gboolean ret = FALSE; GladeWidget *parent; parent = glade_widget_get_parent (property->priv->widget); if (glade_property_class_get_is_packing (property->priv->klass) && parent) ret = glade_widget_adaptor_child_verify_property (glade_widget_get_adaptor (parent), glade_widget_get_object (parent), glade_widget_get_object (property->priv->widget), glade_property_class_id (property->priv->klass), value); else if (!glade_property_class_get_is_packing (property->priv->klass)) ret = glade_widget_adaptor_verify_property (glade_widget_get_adaptor (property->priv->widget), glade_widget_get_object (property->priv->widget), glade_property_class_id (property->priv->klass), value); return ret; }
static void glade_property_load_impl (GladeProperty * property) { GObject *object; GObjectClass *oclass; GParamSpec *pspec; pspec = glade_property_class_get_pspec (property->priv->klass); if (property->priv->widget == NULL || glade_property_class_get_virtual (property->priv->klass) || glade_property_class_get_is_packing (property->priv->klass) || glade_property_class_get_ignore (property->priv->klass) || !(pspec->flags & G_PARAM_READABLE) || G_IS_PARAM_SPEC_OBJECT (pspec)) return; object = glade_widget_get_object (property->priv->widget); oclass = G_OBJECT_GET_CLASS (object); if (g_object_class_find_property (oclass, glade_property_class_id (property->priv->klass))) glade_widget_object_get_property (property->priv->widget, glade_property_class_id (property->priv->klass), property->priv->value); }
static void glade_property_sync_impl (GladeProperty * property) { /* Heh, here are the many reasons not to * sync a property ;-) */ if (/* the class can be NULL during object, * construction this is just a temporary state */ property->priv->klass == NULL || /* optional properties that are disabled */ property->priv->enabled == FALSE || /* explicit "never sync" flag */ glade_property_class_get_ignore (property->priv->klass) || /* recursion guards */ property->priv->syncing >= property->priv->sync_tolerance || /* No widget owns this property yet */ property->priv->widget == NULL) return; /* Only the properties from widget->properties should affect the runtime widget. * (other properties may be used for convenience in the plugin). */ if ((glade_property_class_get_is_packing (property->priv->klass) && !glade_widget_get_pack_property (property->priv->widget, glade_property_class_id (property->priv->klass))) || !glade_widget_get_property (property->priv->widget, glade_property_class_id (property->priv->klass))) return; property->priv->syncing++; /* In the case of construct_only, the widget instance must be rebuilt * to apply the property */ if (glade_property_class_get_construct_only (property->priv->klass) && property->priv->syncing == 1) { /* Virtual properties can be construct only, in which * case they are allowed to trigger a rebuild, and in * the process are allowed to get "synced" after the * instance is rebuilt. */ if (glade_property_class_get_virtual (property->priv->klass)) property->priv->sync_tolerance++; glade_widget_rebuild (property->priv->widget); if (glade_property_class_get_virtual (property->priv->klass)) property->priv->sync_tolerance--; } else if (glade_property_class_get_is_packing (property->priv->klass)) glade_widget_child_set_property (glade_widget_get_parent (property->priv->widget), property->priv->widget, glade_property_class_id (property->priv->klass), property->priv->value); else glade_widget_object_set_property (property->priv->widget, glade_property_class_id (property->priv->klass), property->priv->value); property->priv->syncing--; }
static gboolean glade_property_set_value_impl (GladeProperty * property, const GValue * value) { GladeProject *project = property->priv->widget ? glade_widget_get_project (property->priv->widget) : NULL; gboolean changed = FALSE; GValue old_value = { 0, }; gboolean warn_before, warn_after; #ifdef GLADE_ENABLE_DEBUG if (glade_get_debug_flags () & GLADE_DEBUG_PROPERTIES) { g_print ("PROPERTY: Setting %s property %s on %s ", glade_property_class_get_is_packing (property->priv->klass) ? "packing" : "normal", glade_property_class_id (property->priv->klass), property->priv->widget ? glade_widget_get_name (property->priv->widget) : "unknown"); gchar *str1 = glade_widget_adaptor_string_from_value (glade_property_class_get_adaptor (property->priv->klass), property->priv->klass, property->priv->value); gchar *str2 = glade_widget_adaptor_string_from_value (glade_property_class_get_adaptor (property->priv->klass), property->priv->klass, value); g_print ("from %s to %s\n", str1, str2); g_free (str1); g_free (str2); } #endif /* GLADE_ENABLE_DEBUG */ if (!g_value_type_compatible (G_VALUE_TYPE (property->priv->value), G_VALUE_TYPE (value))) { g_warning ("Trying to assign an incompatible value to property %s\n", glade_property_class_id (property->priv->klass)); return FALSE; } /* Check if the backend doesnt give us permission to * set this value. */ if (glade_property_superuser () == FALSE && property->priv->widget && project && glade_project_is_loading (project) == FALSE && glade_property_verify (property, value) == FALSE) { return FALSE; } /* save "changed" state. */ changed = !glade_property_equals_value (property, value); /* Add/Remove references from widget ref stacks here * (before assigning the value) */ if (property->priv->widget && changed && glade_property_class_is_object (property->priv->klass)) glade_property_update_prop_refs (property, property->priv->value, value); /* Check pre-changed warning state */ warn_before = glade_property_warn_usage (property); /* Make a copy of the old value */ g_value_init (&old_value, G_VALUE_TYPE (property->priv->value)); g_value_copy (property->priv->value, &old_value); /* Assign property first so that; if the object need be * rebuilt, it will reflect the new value */ g_value_reset (property->priv->value); g_value_copy (value, property->priv->value); GLADE_PROPERTY_GET_KLASS (property)->sync (property); glade_property_fix_state (property); if (changed && property->priv->widget) { g_signal_emit (G_OBJECT (property), glade_property_signals[VALUE_CHANGED], 0, &old_value, property->priv->value); glade_project_verify_property (property); /* Check post change warning state */ warn_after = glade_property_warn_usage (property); /* Update owning widget's warning state if need be */ if (property->priv->widget != NULL && warn_before != warn_after) glade_widget_verify (property->priv->widget); } /* Special case parentless widget properties */ if (glade_property_class_parentless_widget (property->priv->klass)) { GladeWidget *gobj; GObject *obj; if ((obj = g_value_get_object (&old_value)) && (gobj = glade_widget_get_from_gobject (obj))) glade_widget_show (gobj); if ((obj = g_value_get_object (value)) && (gobj = glade_widget_get_from_gobject (obj))) glade_widget_hide (gobj); } g_value_unset (&old_value); return TRUE; }