mirror of
https://gitlab.gnome.org/GNOME/glade.git
synced 2025-12-07 00:03:12 -05:00
1576 lines
46 KiB
C
1576 lines
46 KiB
C
/*
|
|
* Copyright (C) 2001 Ximian, Inc.
|
|
* Copyright (C) 2006 The GNOME Foundation.
|
|
*
|
|
* This program is free software; you can redistribute it and/or modify
|
|
* it under the terms of the GNU General Public License as
|
|
* published by the Free Software Foundation; either version 2 of the
|
|
* License, or (at your option) any later version.
|
|
*
|
|
* This program 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 General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with this program; if not, write to the Free Software
|
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
|
*
|
|
* Authors:
|
|
* Chema Celorio <chema@celorio.com>
|
|
* Tristan Van Berkom <tvb@gnome.org>
|
|
*/
|
|
|
|
#ifdef HAVE_CONFIG_H
|
|
#include <config.h>
|
|
#endif
|
|
|
|
/**
|
|
* SECTION:glade-property
|
|
* @Title: GladeProperty
|
|
* @Short_Description: An interface to properties on the #GladeWidget.
|
|
*
|
|
* Every object property of every #GladeWidget in every #GladeProject has
|
|
* a #GladeProperty to interface with, #GladeProperty provides a means
|
|
* to handle properties in the runtime environment.
|
|
*
|
|
* A #GladeProperty can be seen as an instance of a #GladePropertyClass,
|
|
* the #GladePropertyClass describes how a #GladeProperty will function.
|
|
*/
|
|
|
|
#include <stdio.h>
|
|
#include <stdlib.h> /* for atoi and atof */
|
|
#include <string.h>
|
|
|
|
#include <glib/gi18n-lib.h>
|
|
|
|
#include "glade.h"
|
|
#include "glade-widget.h"
|
|
#include "glade-property.h"
|
|
#include "glade-property-class.h"
|
|
#include "glade-project.h"
|
|
#include "glade-widget-adaptor.h"
|
|
#include "glade-debug.h"
|
|
#include "glade-app.h"
|
|
#include "glade-editor.h"
|
|
#include "glade-marshallers.h"
|
|
|
|
struct _GladePropertyPrivate {
|
|
|
|
GladePropertyClass *klass; /* A pointer to the GladeProperty that this
|
|
* setting specifies
|
|
*/
|
|
GladeWidget *widget; /* A pointer to the GladeWidget that this
|
|
* GladeProperty is modifying
|
|
*/
|
|
|
|
GladePropertyState state; /* Current property state, used by editing widgets.
|
|
*/
|
|
|
|
GValue *value; /* The value of the property
|
|
*/
|
|
|
|
gchar *insensitive_tooltip; /* Tooltip to display when in insensitive state
|
|
* (used to explain why the property is
|
|
* insensitive)
|
|
*/
|
|
|
|
gchar *support_warning; /* Tooltip to display when the property
|
|
* has format problems
|
|
* (used to explain why the property is
|
|
* insensitive)
|
|
*/
|
|
guint support_disabled : 1; /* Whether this property is disabled due
|
|
* to format conflicts
|
|
*/
|
|
|
|
guint sensitive : 1; /* Whether this property is sensitive (if the
|
|
* property is "optional" this takes precedence).
|
|
*/
|
|
|
|
guint enabled : 1; /* Enabled is a flag that is used for GladeProperties
|
|
* that have the optional flag set to let us know
|
|
* if this widget has this setting enabled or
|
|
* not. (Like default size, it can be specified or
|
|
* unspecified). This flag also sets the state
|
|
* of the property->input state for the loaded
|
|
* widget.
|
|
*/
|
|
|
|
guint save_always : 1; /* Used to make a special case exception and always
|
|
* save this property regardless of what the default
|
|
* value is (used for some special cases like properties
|
|
* that are assigned initial values in composite widgets
|
|
* or derived widget code).
|
|
*/
|
|
|
|
/* Used only for translatable strings. */
|
|
guint i18n_translatable : 1;
|
|
gchar *i18n_context;
|
|
gchar *i18n_comment;
|
|
|
|
gint syncing; /* Avoid recursion while synchronizing object with value */
|
|
gint sync_tolerance;
|
|
};
|
|
|
|
enum
|
|
{
|
|
VALUE_CHANGED,
|
|
TOOLTIP_CHANGED,
|
|
LAST_SIGNAL
|
|
};
|
|
|
|
enum
|
|
{
|
|
PROP_0,
|
|
PROP_CLASS,
|
|
PROP_ENABLED,
|
|
PROP_SENSITIVE,
|
|
PROP_I18N_TRANSLATABLE,
|
|
PROP_I18N_CONTEXT,
|
|
PROP_I18N_COMMENT,
|
|
PROP_STATE,
|
|
N_PROPERTIES
|
|
};
|
|
|
|
static GParamSpec *properties[N_PROPERTIES];
|
|
static guint glade_property_signals[LAST_SIGNAL] = { 0 };
|
|
|
|
static GObjectClass *parent_class = NULL;
|
|
|
|
/*******************************************************************************
|
|
GladeProperty class methods
|
|
*******************************************************************************/
|
|
static GladeProperty *
|
|
glade_property_dup_impl (GladeProperty * template_prop, GladeWidget * widget)
|
|
{
|
|
GladeProperty *property;
|
|
|
|
property = g_object_new (GLADE_TYPE_PROPERTY,
|
|
"class", template_prop->priv->klass,
|
|
"i18n-translatable", template_prop->priv->i18n_translatable,
|
|
"i18n-context", template_prop->priv->i18n_context,
|
|
"i18n-comment", template_prop->priv->i18n_comment,
|
|
NULL);
|
|
property->priv->widget = widget;
|
|
property->priv->value = g_new0 (GValue, 1);
|
|
|
|
g_value_init (property->priv->value, template_prop->priv->value->g_type);
|
|
|
|
/* Cannot duplicate parentless_widget property */
|
|
if (glade_property_class_parentless_widget (template_prop->priv->klass))
|
|
{
|
|
if (!G_IS_PARAM_SPEC_OBJECT (glade_property_class_get_pspec (template_prop->priv->klass)))
|
|
g_warning ("Parentless widget property should be of object type");
|
|
|
|
g_value_set_object (property->priv->value, NULL);
|
|
}
|
|
else
|
|
g_value_copy (template_prop->priv->value, property->priv->value);
|
|
|
|
property->priv->enabled = template_prop->priv->enabled;
|
|
property->priv->state = template_prop->priv->state;
|
|
|
|
glade_property_set_sensitive (property, template_prop->priv->sensitive,
|
|
template_prop->priv->insensitive_tooltip);
|
|
|
|
return property;
|
|
}
|
|
|
|
static gboolean
|
|
glade_property_equals_value_impl (GladeProperty * property,
|
|
const GValue * value)
|
|
{
|
|
return !glade_property_class_compare (property->priv->klass, property->priv->value,
|
|
value);
|
|
}
|
|
|
|
|
|
static void
|
|
glade_property_update_prop_refs (GladeProperty * property,
|
|
const GValue * old_value,
|
|
const GValue * new_value)
|
|
{
|
|
GladeWidget *gold, *gnew;
|
|
GObject *old_object, *new_object;
|
|
GList *old_list, *new_list, *list, *removed, *added;
|
|
|
|
if (GLADE_IS_PARAM_SPEC_OBJECTS (glade_property_class_get_pspec (property->priv->klass)))
|
|
{
|
|
/* Make our own copies incase we're walking an
|
|
* unstable list
|
|
*/
|
|
old_list = g_value_dup_boxed (old_value);
|
|
new_list = g_value_dup_boxed (new_value);
|
|
|
|
/* Diff up the GList */
|
|
removed = glade_util_removed_from_list (old_list, new_list);
|
|
added = glade_util_added_in_list (old_list, new_list);
|
|
|
|
/* Adjust the appropriate prop refs */
|
|
for (list = removed; list; list = list->next)
|
|
{
|
|
old_object = list->data;
|
|
gold = glade_widget_get_from_gobject (old_object);
|
|
if (gold != NULL)
|
|
glade_widget_remove_prop_ref (gold, property);
|
|
}
|
|
for (list = added; list; list = list->next)
|
|
{
|
|
new_object = list->data;
|
|
gnew = glade_widget_get_from_gobject (new_object);
|
|
if (gnew != NULL)
|
|
glade_widget_add_prop_ref (gnew, property);
|
|
}
|
|
|
|
g_list_free (removed);
|
|
g_list_free (added);
|
|
g_list_free (old_list);
|
|
g_list_free (new_list);
|
|
}
|
|
else
|
|
{
|
|
if ((old_object = g_value_get_object (old_value)) != NULL)
|
|
{
|
|
gold = glade_widget_get_from_gobject (old_object);
|
|
g_return_if_fail (gold != NULL);
|
|
glade_widget_remove_prop_ref (gold, property);
|
|
}
|
|
|
|
if ((new_object = g_value_get_object (new_value)) != NULL)
|
|
{
|
|
gnew = glade_widget_get_from_gobject (new_object);
|
|
g_return_if_fail (gnew != NULL);
|
|
glade_widget_add_prop_ref (gnew, property);
|
|
}
|
|
}
|
|
}
|
|
|
|
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_fix_state (GladeProperty * property)
|
|
{
|
|
property->priv->state = GLADE_STATE_NORMAL;
|
|
|
|
if (!glade_property_original_default (property))
|
|
property->priv->state = GLADE_STATE_CHANGED;
|
|
|
|
if (property->priv->support_warning)
|
|
property->priv->state |= GLADE_STATE_UNSUPPORTED;
|
|
|
|
if (property->priv->support_disabled)
|
|
property->priv->state |= GLADE_STATE_SUPPORT_DISABLED;
|
|
|
|
g_object_notify_by_pspec (G_OBJECT (property), properties[PROP_STATE]);
|
|
}
|
|
|
|
|
|
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, };
|
|
|
|
#if 0
|
|
{
|
|
g_print ("***************************************************\n");
|
|
g_print ("Setting %s property %s on %s ..\n",
|
|
property->priv->klass->packing ? "packing" : "normal",
|
|
property->priv->klass->id,
|
|
property->priv->widget ? property->priv->widget->name : "unknown");
|
|
|
|
gchar *str1 = glade_widget_adaptor_string_from_value
|
|
(GLADE_WIDGET_ADAPTOR (property->priv->klass->handle),
|
|
property->priv->klass, property->priv->value);
|
|
gchar *str2 = glade_widget_adaptor_string_from_value
|
|
(GLADE_WIDGET_ADAPTOR (property->priv->klass->handle),
|
|
property->priv->klass, value);
|
|
g_print ("from %s to %s\n", str1, str2);
|
|
g_free (str1);
|
|
g_free (str2);
|
|
}
|
|
#endif
|
|
|
|
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);
|
|
|
|
|
|
/* 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);
|
|
}
|
|
|
|
/* 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;
|
|
}
|
|
|
|
static void
|
|
glade_property_get_value_impl (GladeProperty * property, GValue * value)
|
|
{
|
|
GParamSpec *pspec;
|
|
|
|
pspec = glade_property_class_get_pspec (property->priv->klass);
|
|
|
|
g_value_init (value, pspec->value_type);
|
|
g_value_copy (property->priv->value, 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 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);
|
|
}
|
|
|
|
/*******************************************************************************
|
|
GObjectClass & Object Construction
|
|
*******************************************************************************/
|
|
static void
|
|
glade_property_set_real_property (GObject * object,
|
|
guint prop_id,
|
|
const GValue * value, GParamSpec * pspec)
|
|
{
|
|
GladeProperty *property = GLADE_PROPERTY (object);
|
|
|
|
switch (prop_id)
|
|
{
|
|
case PROP_CLASS:
|
|
property->priv->klass = g_value_get_pointer (value);
|
|
break;
|
|
case PROP_ENABLED:
|
|
glade_property_set_enabled (property, g_value_get_boolean (value));
|
|
break;
|
|
case PROP_SENSITIVE:
|
|
property->priv->sensitive = g_value_get_boolean (value);
|
|
break;
|
|
case PROP_I18N_TRANSLATABLE:
|
|
glade_property_i18n_set_translatable (property,
|
|
g_value_get_boolean (value));
|
|
break;
|
|
case PROP_I18N_CONTEXT:
|
|
glade_property_i18n_set_context (property, g_value_get_string (value));
|
|
break;
|
|
case PROP_I18N_COMMENT:
|
|
glade_property_i18n_set_comment (property, g_value_get_string (value));
|
|
break;
|
|
default:
|
|
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
|
break;
|
|
}
|
|
}
|
|
|
|
static void
|
|
glade_property_get_real_property (GObject * object,
|
|
guint prop_id,
|
|
GValue * value, GParamSpec * pspec)
|
|
{
|
|
GladeProperty *property = GLADE_PROPERTY (object);
|
|
|
|
switch (prop_id)
|
|
{
|
|
case PROP_CLASS:
|
|
g_value_set_pointer (value, property->priv->klass);
|
|
break;
|
|
case PROP_ENABLED:
|
|
g_value_set_boolean (value, glade_property_get_enabled (property));
|
|
break;
|
|
case PROP_SENSITIVE:
|
|
g_value_set_boolean (value, glade_property_get_sensitive (property));
|
|
break;
|
|
case PROP_I18N_TRANSLATABLE:
|
|
g_value_set_boolean (value,
|
|
glade_property_i18n_get_translatable (property));
|
|
break;
|
|
case PROP_I18N_CONTEXT:
|
|
g_value_set_string (value, glade_property_i18n_get_context (property));
|
|
break;
|
|
case PROP_I18N_COMMENT:
|
|
g_value_set_string (value, glade_property_i18n_get_comment (property));
|
|
break;
|
|
case PROP_STATE:
|
|
g_value_set_int (value, property->priv->state);
|
|
break;
|
|
default:
|
|
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
|
break;
|
|
}
|
|
}
|
|
|
|
static void
|
|
glade_property_finalize (GObject * object)
|
|
{
|
|
GladeProperty *property = GLADE_PROPERTY (object);
|
|
|
|
if (property->priv->value)
|
|
{
|
|
g_value_unset (property->priv->value);
|
|
g_free (property->priv->value);
|
|
}
|
|
if (property->priv->i18n_comment)
|
|
g_free (property->priv->i18n_comment);
|
|
if (property->priv->i18n_context)
|
|
g_free (property->priv->i18n_context);
|
|
if (property->priv->support_warning)
|
|
g_free (property->priv->support_warning);
|
|
if (property->priv->insensitive_tooltip)
|
|
g_free (property->priv->insensitive_tooltip);
|
|
|
|
G_OBJECT_CLASS (parent_class)->finalize (object);
|
|
}
|
|
|
|
static void
|
|
glade_property_init (GladeProperty * property)
|
|
{
|
|
property->priv = G_TYPE_INSTANCE_GET_PRIVATE (property,
|
|
GLADE_TYPE_PROPERTY,
|
|
GladePropertyPrivate);
|
|
|
|
property->priv->enabled = TRUE;
|
|
property->priv->sensitive = TRUE;
|
|
property->priv->i18n_translatable = TRUE;
|
|
property->priv->i18n_comment = NULL;
|
|
property->priv->sync_tolerance = 1;
|
|
}
|
|
|
|
static void
|
|
glade_property_klass_init (GladePropertyKlass * prop_class)
|
|
{
|
|
GObjectClass *object_class;
|
|
g_return_if_fail (prop_class != NULL);
|
|
|
|
parent_class = g_type_class_peek_parent (prop_class);
|
|
object_class = G_OBJECT_CLASS (prop_class);
|
|
|
|
/* GObjectClass */
|
|
object_class->set_property = glade_property_set_real_property;
|
|
object_class->get_property = glade_property_get_real_property;
|
|
object_class->finalize = glade_property_finalize;
|
|
|
|
/* Class methods */
|
|
prop_class->dup = glade_property_dup_impl;
|
|
prop_class->equals_value = glade_property_equals_value_impl;
|
|
prop_class->set_value = glade_property_set_value_impl;
|
|
prop_class->get_value = glade_property_get_value_impl;
|
|
prop_class->sync = glade_property_sync_impl;
|
|
prop_class->load = glade_property_load_impl;
|
|
prop_class->value_changed = NULL;
|
|
prop_class->tooltip_changed = NULL;
|
|
|
|
/* Properties */
|
|
properties[PROP_CLASS] =
|
|
g_param_spec_pointer ("class",
|
|
_("Class"),
|
|
_("The GladePropertyClass for this property"),
|
|
G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE);
|
|
|
|
properties[PROP_ENABLED] =
|
|
g_param_spec_boolean ("enabled",
|
|
_("Enabled"),
|
|
_("If the property is optional, this is its enabled state"),
|
|
TRUE, G_PARAM_READWRITE);
|
|
|
|
properties[PROP_SENSITIVE] =
|
|
g_param_spec_boolean ("sensitive",
|
|
_("Sensitive"),
|
|
_("This gives backends control to set property sensitivity"),
|
|
TRUE, G_PARAM_READWRITE);
|
|
|
|
properties[PROP_I18N_CONTEXT] =
|
|
g_param_spec_string ("i18n-context",
|
|
_("Context"),
|
|
_("Context for translation"),
|
|
NULL,
|
|
G_PARAM_READWRITE);
|
|
|
|
properties[PROP_I18N_COMMENT] =
|
|
g_param_spec_string ("i18n-comment",
|
|
_("Comment"),
|
|
_("Comment for translators"),
|
|
NULL,
|
|
G_PARAM_READWRITE);
|
|
|
|
properties[PROP_I18N_TRANSLATABLE] =
|
|
g_param_spec_boolean ("i18n-translatable",
|
|
_("Translatable"),
|
|
_("Whether this property is translatable"),
|
|
TRUE,
|
|
G_PARAM_READWRITE);
|
|
|
|
properties[PROP_STATE] =
|
|
g_param_spec_int ("state",
|
|
_("Visual State"),
|
|
_("Priority information for the property editor to act on"),
|
|
GLADE_STATE_NORMAL,
|
|
G_MAXINT,
|
|
GLADE_STATE_NORMAL,
|
|
G_PARAM_READABLE);
|
|
|
|
/* Install all properties */
|
|
g_object_class_install_properties (object_class, N_PROPERTIES, properties);
|
|
|
|
/* Signal */
|
|
glade_property_signals[VALUE_CHANGED] =
|
|
g_signal_new ("value-changed",
|
|
G_TYPE_FROM_CLASS (object_class),
|
|
G_SIGNAL_RUN_LAST,
|
|
G_STRUCT_OFFSET (GladePropertyKlass,
|
|
value_changed),
|
|
NULL, NULL,
|
|
_glade_marshal_VOID__POINTER_POINTER,
|
|
G_TYPE_NONE, 2, G_TYPE_POINTER, G_TYPE_POINTER);
|
|
|
|
glade_property_signals[TOOLTIP_CHANGED] =
|
|
g_signal_new ("tooltip-changed",
|
|
G_TYPE_FROM_CLASS (object_class),
|
|
G_SIGNAL_RUN_LAST,
|
|
G_STRUCT_OFFSET (GladePropertyKlass,
|
|
tooltip_changed),
|
|
NULL, NULL,
|
|
_glade_marshal_VOID__STRING_STRING_STRING,
|
|
G_TYPE_NONE, 3, G_TYPE_STRING, G_TYPE_STRING,
|
|
G_TYPE_STRING);
|
|
|
|
g_type_class_add_private (prop_class, sizeof (GladePropertyPrivate));
|
|
}
|
|
|
|
GType
|
|
glade_property_get_type (void)
|
|
{
|
|
static GType property_type = 0;
|
|
|
|
if (!property_type)
|
|
{
|
|
static const GTypeInfo property_info = {
|
|
sizeof (GladePropertyKlass), /* Klass is our class */
|
|
(GBaseInitFunc) NULL,
|
|
(GBaseFinalizeFunc) NULL,
|
|
(GClassInitFunc) glade_property_klass_init,
|
|
(GClassFinalizeFunc) NULL,
|
|
NULL, /* class_data */
|
|
sizeof (GladeProperty),
|
|
0, /* n_preallocs */
|
|
(GInstanceInitFunc) glade_property_init,
|
|
};
|
|
property_type =
|
|
g_type_register_static (G_TYPE_OBJECT,
|
|
"GladeProperty", &property_info, 0);
|
|
}
|
|
return property_type;
|
|
}
|
|
|
|
/*******************************************************************************
|
|
API
|
|
*******************************************************************************/
|
|
/**
|
|
* glade_property_new:
|
|
* @klass: A #GladePropertyClass defining this property
|
|
* @widget: The #GladeWidget this property is created for
|
|
* @value: The initial #GValue of the property or %NULL
|
|
* (the #GladeProperty will assume ownership of @value)
|
|
*
|
|
* Creates a #GladeProperty of type @klass for @widget with @value; if
|
|
* @value is %NULL, then the introspected default value for that property
|
|
* will be used.
|
|
*
|
|
* Returns: The newly created #GladeProperty
|
|
*/
|
|
GladeProperty *
|
|
glade_property_new (GladePropertyClass * klass,
|
|
GladeWidget * widget, GValue * value)
|
|
{
|
|
GladeProperty *property;
|
|
|
|
g_return_val_if_fail (GLADE_IS_PROPERTY_CLASS (klass), NULL);
|
|
|
|
property = (GladeProperty *) g_object_new (GLADE_TYPE_PROPERTY, NULL);
|
|
property->priv->klass = klass;
|
|
property->priv->widget = widget;
|
|
property->priv->value = value;
|
|
|
|
if (glade_property_class_optional (klass))
|
|
property->priv->enabled = glade_property_class_optional_default (klass);
|
|
|
|
if (property->priv->value == NULL)
|
|
{
|
|
const GValue *orig_def =
|
|
glade_property_class_get_original_default (klass);
|
|
|
|
property->priv->value = g_new0 (GValue, 1);
|
|
g_value_init (property->priv->value, orig_def->g_type);
|
|
g_value_copy (orig_def, property->priv->value);
|
|
}
|
|
return property;
|
|
}
|
|
|
|
/**
|
|
* glade_property_dup:
|
|
* @template_prop: A #GladeProperty
|
|
* @widget: A #GladeWidget
|
|
*
|
|
* Returns: A newly duplicated property based on the new widget
|
|
*/
|
|
GladeProperty *
|
|
glade_property_dup (GladeProperty * template_prop, GladeWidget * widget)
|
|
{
|
|
g_return_val_if_fail (GLADE_IS_PROPERTY (template_prop), NULL);
|
|
return GLADE_PROPERTY_GET_KLASS (template_prop)->dup (template_prop, widget);
|
|
}
|
|
|
|
static void
|
|
glade_property_reset_common (GladeProperty * property, gboolean original)
|
|
{
|
|
const GValue *value;
|
|
|
|
g_return_if_fail (GLADE_IS_PROPERTY (property));
|
|
|
|
if (original)
|
|
value = glade_property_class_get_original_default (property->priv->klass);
|
|
else
|
|
value = glade_property_class_get_default (property->priv->klass);
|
|
|
|
GLADE_PROPERTY_GET_KLASS (property)->set_value (property, value);
|
|
}
|
|
|
|
/**
|
|
* glade_property_reset:
|
|
* @property: A #GladeProperty
|
|
*
|
|
* Resets this property to its default value
|
|
*/
|
|
void
|
|
glade_property_reset (GladeProperty * property)
|
|
{
|
|
glade_property_reset_common (property, FALSE);
|
|
}
|
|
|
|
/**
|
|
* glade_property_original_reset:
|
|
* @property: A #GladeProperty
|
|
*
|
|
* Resets this property to its original default value
|
|
*/
|
|
void
|
|
glade_property_original_reset (GladeProperty * property)
|
|
{
|
|
glade_property_reset_common (property, TRUE);
|
|
}
|
|
|
|
static gboolean
|
|
glade_property_default_common (GladeProperty * property, gboolean orig)
|
|
{
|
|
const GValue *value;
|
|
|
|
g_return_val_if_fail (GLADE_IS_PROPERTY (property), FALSE);
|
|
|
|
if (orig)
|
|
value = glade_property_class_get_original_default (property->priv->klass);
|
|
else
|
|
value = glade_property_class_get_default (property->priv->klass);
|
|
|
|
return GLADE_PROPERTY_GET_KLASS (property)->equals_value (property, value);
|
|
}
|
|
|
|
/**
|
|
* glade_property_default:
|
|
* @property: A #GladeProperty
|
|
*
|
|
* Returns: Whether this property is at its default value
|
|
*/
|
|
gboolean
|
|
glade_property_default (GladeProperty * property)
|
|
{
|
|
return glade_property_default_common (property, FALSE);
|
|
}
|
|
|
|
/**
|
|
* glade_property_original_default:
|
|
* @property: A #GladeProperty
|
|
*
|
|
* Returns: Whether this property is at its original default value
|
|
*/
|
|
gboolean
|
|
glade_property_original_default (GladeProperty * property)
|
|
{
|
|
return glade_property_default_common (property, TRUE);
|
|
}
|
|
|
|
/**
|
|
* glade_property_equals_value:
|
|
* @property: a #GladeProperty
|
|
* @value: a #GValue
|
|
*
|
|
* Returns: Whether this property is equal to the value provided
|
|
*/
|
|
gboolean
|
|
glade_property_equals_value (GladeProperty * property, const GValue * value)
|
|
{
|
|
g_return_val_if_fail (GLADE_IS_PROPERTY (property), FALSE);
|
|
return GLADE_PROPERTY_GET_KLASS (property)->equals_value (property, value);
|
|
}
|
|
|
|
/**
|
|
* glade_property_equals_va_list:
|
|
* @property: a #GladeProperty
|
|
* @vl: a va_list
|
|
*
|
|
* Returns: Whether this property is equal to the value provided
|
|
*/
|
|
static gboolean
|
|
glade_property_equals_va_list (GladeProperty * property, va_list vl)
|
|
{
|
|
GValue *value;
|
|
gboolean ret;
|
|
|
|
g_return_val_if_fail (GLADE_IS_PROPERTY (property), FALSE);
|
|
|
|
value = glade_property_class_make_gvalue_from_vl (property->priv->klass, vl);
|
|
|
|
ret = GLADE_PROPERTY_GET_KLASS (property)->equals_value (property, value);
|
|
|
|
g_value_unset (value);
|
|
g_free (value);
|
|
return ret;
|
|
}
|
|
|
|
/**
|
|
* glade_property_equals:
|
|
* @property: a #GladeProperty
|
|
* @...: a provided property value
|
|
*
|
|
* Returns: Whether this property is equal to the value provided
|
|
*/
|
|
gboolean
|
|
glade_property_equals (GladeProperty * property, ...)
|
|
{
|
|
va_list vl;
|
|
gboolean ret;
|
|
|
|
g_return_val_if_fail (GLADE_IS_PROPERTY (property), FALSE);
|
|
|
|
va_start (vl, property);
|
|
ret = glade_property_equals_va_list (property, vl);
|
|
va_end (vl);
|
|
|
|
return ret;
|
|
}
|
|
|
|
/**
|
|
* glade_property_set_value:
|
|
* @property: a #GladeProperty
|
|
* @value: a #GValue
|
|
*
|
|
* Sets the property's value
|
|
*
|
|
* Returns: Whether the property was successfully set.
|
|
*/
|
|
gboolean
|
|
glade_property_set_value (GladeProperty * property, const GValue * value)
|
|
{
|
|
g_return_val_if_fail (GLADE_IS_PROPERTY (property), FALSE);
|
|
g_return_val_if_fail (value != NULL, FALSE);
|
|
return GLADE_PROPERTY_GET_KLASS (property)->set_value (property, value);
|
|
}
|
|
|
|
/**
|
|
* glade_property_set_va_list:
|
|
* @property: a #GladeProperty
|
|
* @vl: a va_list with value to set
|
|
*
|
|
* Sets the property's value
|
|
*/
|
|
gboolean
|
|
glade_property_set_va_list (GladeProperty * property, va_list vl)
|
|
{
|
|
GValue *value;
|
|
gboolean success;
|
|
|
|
g_return_val_if_fail (GLADE_IS_PROPERTY (property), FALSE);
|
|
|
|
value = glade_property_class_make_gvalue_from_vl (property->priv->klass, vl);
|
|
|
|
success = GLADE_PROPERTY_GET_KLASS (property)->set_value (property, value);
|
|
|
|
g_value_unset (value);
|
|
g_free (value);
|
|
|
|
return success;
|
|
}
|
|
|
|
/**
|
|
* glade_property_set:
|
|
* @property: a #GladeProperty
|
|
* @...: the value to set
|
|
*
|
|
* Sets the property's value (in a convenient way)
|
|
*/
|
|
gboolean
|
|
glade_property_set (GladeProperty * property, ...)
|
|
{
|
|
va_list vl;
|
|
gboolean success;
|
|
|
|
g_return_val_if_fail (GLADE_IS_PROPERTY (property), FALSE);
|
|
|
|
va_start (vl, property);
|
|
success = glade_property_set_va_list (property, vl);
|
|
va_end (vl);
|
|
|
|
return success;
|
|
}
|
|
|
|
/**
|
|
* glade_property_get_value:
|
|
* @property: a #GladeProperty
|
|
* @value: a #GValue
|
|
*
|
|
* Retrieve the property value
|
|
*/
|
|
void
|
|
glade_property_get_value (GladeProperty * property, GValue * value)
|
|
{
|
|
g_return_if_fail (GLADE_IS_PROPERTY (property));
|
|
g_return_if_fail (value != NULL);
|
|
GLADE_PROPERTY_GET_KLASS (property)->get_value (property, value);
|
|
}
|
|
|
|
/**
|
|
* glade_property_get_default:
|
|
* @property: a #GladeProperty
|
|
* @value: a #GValue
|
|
*
|
|
* Retrieve the default property value
|
|
*/
|
|
void
|
|
glade_property_get_default (GladeProperty * property, GValue * value)
|
|
{
|
|
GParamSpec *pspec;
|
|
|
|
g_return_if_fail (GLADE_IS_PROPERTY (property));
|
|
g_return_if_fail (value != NULL);
|
|
|
|
pspec = glade_property_class_get_pspec (property->priv->klass);
|
|
g_value_init (value, pspec->value_type);
|
|
g_value_copy (glade_property_class_get_default (property->priv->klass), value);
|
|
}
|
|
|
|
/**
|
|
* glade_property_get_va_list:
|
|
* @property: a #GladeProperty
|
|
* @vl: a va_list
|
|
*
|
|
* Retrieve the property value
|
|
*/
|
|
void
|
|
glade_property_get_va_list (GladeProperty * property, va_list vl)
|
|
{
|
|
g_return_if_fail (GLADE_IS_PROPERTY (property));
|
|
glade_property_class_set_vl_from_gvalue (property->priv->klass, property->priv->value,
|
|
vl);
|
|
}
|
|
|
|
/**
|
|
* glade_property_get:
|
|
* @property: a #GladeProperty
|
|
* @...: An address to store the value
|
|
*
|
|
* Retrieve the property value
|
|
*/
|
|
void
|
|
glade_property_get (GladeProperty * property, ...)
|
|
{
|
|
va_list vl;
|
|
|
|
g_return_if_fail (GLADE_IS_PROPERTY (property));
|
|
|
|
va_start (vl, property);
|
|
glade_property_get_va_list (property, vl);
|
|
va_end (vl);
|
|
}
|
|
|
|
/**
|
|
* glade_property_sync:
|
|
* @property: a #GladeProperty
|
|
*
|
|
* Synchronize the object with this property
|
|
*/
|
|
void
|
|
glade_property_sync (GladeProperty * property)
|
|
{
|
|
g_return_if_fail (GLADE_IS_PROPERTY (property));
|
|
GLADE_PROPERTY_GET_KLASS (property)->sync (property);
|
|
}
|
|
|
|
/**
|
|
* glade_property_load:
|
|
* @property: a #GladeProperty
|
|
*
|
|
* Loads the value of @property from the coresponding object instance
|
|
*/
|
|
void
|
|
glade_property_load (GladeProperty * property)
|
|
{
|
|
g_return_if_fail (GLADE_IS_PROPERTY (property));
|
|
GLADE_PROPERTY_GET_KLASS (property)->load (property);
|
|
}
|
|
|
|
/**
|
|
* glade_property_read:
|
|
* @property: a #GladeProperty or #NULL
|
|
* @project: the #GladeProject
|
|
* @node: the #GladeXmlNode to read, will either be a 'widget'
|
|
* node or a 'child' node for packing properties.
|
|
*
|
|
* Read the value and any attributes for @property from @node, assumes
|
|
* @property is being loaded for @project
|
|
*
|
|
* Note that object values will only be resolved after the project is
|
|
* completely loaded
|
|
*/
|
|
void
|
|
glade_property_read (GladeProperty * property,
|
|
GladeProject * project, GladeXmlNode * prop)
|
|
{
|
|
GValue *gvalue = NULL;
|
|
gchar /* *id, *name, */ * value;
|
|
gint translatable = FALSE;
|
|
gchar *comment = NULL, *context = NULL;
|
|
|
|
g_return_if_fail (GLADE_IS_PROPERTY (property));
|
|
g_return_if_fail (GLADE_IS_PROJECT (project));
|
|
g_return_if_fail (prop != NULL);
|
|
|
|
if (!glade_xml_node_verify (prop, GLADE_XML_TAG_PROPERTY))
|
|
return;
|
|
|
|
if (!(value = glade_xml_get_content (prop)))
|
|
return;
|
|
|
|
if (glade_property_class_is_object (property->priv->klass))
|
|
{
|
|
/* we must synchronize this directly after loading this project
|
|
* (i.e. lookup the actual objects after they've been parsed and
|
|
* are present).
|
|
*/
|
|
g_object_set_data_full (G_OBJECT (property),
|
|
"glade-loaded-object", g_strdup (value), g_free);
|
|
}
|
|
else
|
|
{
|
|
/* If an optional property is specified in the
|
|
* glade file, its enabled
|
|
*/
|
|
property->priv->enabled = TRUE;
|
|
|
|
gvalue =
|
|
glade_property_class_make_gvalue_from_string (property->priv->klass, value, project);
|
|
|
|
GLADE_PROPERTY_GET_KLASS (property)->set_value (property, gvalue);
|
|
|
|
g_value_unset (gvalue);
|
|
g_free (gvalue);
|
|
}
|
|
|
|
translatable =
|
|
glade_xml_get_property_boolean (prop, GLADE_TAG_TRANSLATABLE, FALSE);
|
|
comment = glade_xml_get_property_string (prop, GLADE_TAG_COMMENT);
|
|
context = glade_xml_get_property_string (prop, GLADE_TAG_CONTEXT);
|
|
|
|
glade_property_i18n_set_translatable (property, translatable);
|
|
glade_property_i18n_set_comment (property, comment);
|
|
glade_property_i18n_set_context (property, context);
|
|
|
|
g_free (comment);
|
|
g_free (context);
|
|
g_free (value);
|
|
}
|
|
|
|
|
|
/**
|
|
* glade_property_write:
|
|
* @property: a #GladeProperty
|
|
* @context: A #GladeXmlContext
|
|
* @node: A #GladeXmlNode
|
|
*
|
|
* Write @property to @node
|
|
*/
|
|
void
|
|
glade_property_write (GladeProperty * property,
|
|
GladeXmlContext * context, GladeXmlNode * node)
|
|
{
|
|
GladeXmlNode *prop_node;
|
|
gchar *name, *value;
|
|
|
|
g_return_if_fail (GLADE_IS_PROPERTY (property));
|
|
g_return_if_fail (node != NULL);
|
|
|
|
/* This code should work the same for <packing> and <widget> */
|
|
if (!(glade_xml_node_verify_silent (node, GLADE_XML_TAG_PACKING) ||
|
|
glade_xml_node_verify_silent (node, GLADE_XML_TAG_WIDGET)))
|
|
return;
|
|
|
|
/* Skip properties that are default by original pspec default
|
|
* (excepting those that specified otherwise).
|
|
*/
|
|
if (!(glade_property_class_save_always (property->priv->klass) || property->priv->save_always) &&
|
|
glade_property_original_default (property))
|
|
return;
|
|
|
|
/* Escape our string and save with underscores */
|
|
name = g_strdup (glade_property_class_id (property->priv->klass));
|
|
glade_util_replace (name, '-', '_');
|
|
|
|
/* convert the value of this property to a string */
|
|
if (!(value = glade_widget_adaptor_string_from_value
|
|
(glade_property_class_get_adaptor (property->priv->klass), property->priv->klass,
|
|
property->priv->value)))
|
|
/* make sure we keep the empty string, also... upcomming
|
|
* funcs that may not like NULL.
|
|
*/
|
|
value = g_strdup ("");
|
|
|
|
/* Now dump the node values... */
|
|
prop_node = glade_xml_node_new (context, GLADE_XML_TAG_PROPERTY);
|
|
glade_xml_node_append_child (node, prop_node);
|
|
|
|
/* Name and value */
|
|
glade_xml_node_set_property_string (prop_node, GLADE_XML_TAG_NAME, name);
|
|
glade_xml_set_content (prop_node, value);
|
|
|
|
/* i18n stuff */
|
|
if (glade_property_class_translatable (property->priv->klass))
|
|
{
|
|
if (property->priv->i18n_translatable)
|
|
glade_xml_node_set_property_string (prop_node,
|
|
GLADE_TAG_TRANSLATABLE,
|
|
GLADE_XML_TAG_I18N_TRUE);
|
|
|
|
if (property->priv->i18n_context)
|
|
glade_xml_node_set_property_string (prop_node,
|
|
GLADE_TAG_CONTEXT,
|
|
property->priv->i18n_context);
|
|
|
|
if (property->priv->i18n_comment)
|
|
glade_xml_node_set_property_string (prop_node,
|
|
GLADE_TAG_COMMENT,
|
|
property->priv->i18n_comment);
|
|
}
|
|
g_free (name);
|
|
g_free (value);
|
|
}
|
|
|
|
/**
|
|
* glade_property_add_object:
|
|
* @property: a #GladeProperty
|
|
* @object: The #GObject to add
|
|
*
|
|
* Adds @object to the object list in @property.
|
|
*
|
|
* Note: This function expects @property to be a #GladeParamSpecObjects
|
|
* or #GParamSpecObject type property.
|
|
*/
|
|
void
|
|
glade_property_add_object (GladeProperty * property, GObject * object)
|
|
{
|
|
GList *list = NULL, *new_list = NULL;
|
|
GParamSpec *pspec;
|
|
|
|
g_return_if_fail (GLADE_IS_PROPERTY (property));
|
|
g_return_if_fail (G_IS_OBJECT (object));
|
|
|
|
pspec = glade_property_class_get_pspec (property->priv->klass);
|
|
|
|
g_return_if_fail (GLADE_IS_PARAM_SPEC_OBJECTS (pspec) ||
|
|
G_IS_PARAM_SPEC_OBJECT (pspec));
|
|
|
|
if (GLADE_IS_PARAM_SPEC_OBJECTS (pspec))
|
|
{
|
|
glade_property_get (property, &list);
|
|
new_list = g_list_copy (list);
|
|
|
|
new_list = g_list_append (new_list, object);
|
|
glade_property_set (property, new_list);
|
|
|
|
/* ownership of the list is not passed
|
|
* through glade_property_set()
|
|
*/
|
|
g_list_free (new_list);
|
|
}
|
|
else
|
|
{
|
|
glade_property_set (property, object);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* glade_property_remove_object:
|
|
* @property: a #GladeProperty
|
|
* @object: The #GObject to add
|
|
*
|
|
* Removes @object from the object list in @property.
|
|
*
|
|
* Note: This function expects @property to be a #GladeParamSpecObjects
|
|
* or #GParamSpecObject type property.
|
|
*/
|
|
void
|
|
glade_property_remove_object (GladeProperty * property, GObject * object)
|
|
{
|
|
GList *list = NULL, *new_list = NULL;
|
|
GParamSpec *pspec;
|
|
|
|
g_return_if_fail (GLADE_IS_PROPERTY (property));
|
|
g_return_if_fail (G_IS_OBJECT (object));
|
|
|
|
pspec = glade_property_class_get_pspec (property->priv->klass);
|
|
|
|
g_return_if_fail (GLADE_IS_PARAM_SPEC_OBJECTS (pspec) ||
|
|
G_IS_PARAM_SPEC_OBJECT (pspec));
|
|
|
|
if (GLADE_IS_PARAM_SPEC_OBJECTS (pspec))
|
|
{
|
|
/* If object isnt in list; list should stay in tact.
|
|
* not bothering to check for now.
|
|
*/
|
|
glade_property_get (property, &list);
|
|
new_list = g_list_copy (list);
|
|
|
|
new_list = g_list_remove (new_list, object);
|
|
glade_property_set (property, new_list);
|
|
|
|
/* ownership of the list is not passed
|
|
* through glade_property_set()
|
|
*/
|
|
g_list_free (new_list);
|
|
}
|
|
else
|
|
{
|
|
glade_property_set (property, NULL);
|
|
}
|
|
}
|
|
|
|
GladePropertyClass *
|
|
glade_property_get_class (GladeProperty *property)
|
|
{
|
|
g_return_val_if_fail (GLADE_IS_PROPERTY (property), NULL);
|
|
|
|
return property->priv->klass;
|
|
}
|
|
|
|
|
|
/* Parameters for translatable properties. */
|
|
void
|
|
glade_property_i18n_set_comment (GladeProperty * property, const gchar * str)
|
|
{
|
|
g_return_if_fail (GLADE_IS_PROPERTY (property));
|
|
if (property->priv->i18n_comment)
|
|
g_free (property->priv->i18n_comment);
|
|
|
|
property->priv->i18n_comment = g_strdup (str);
|
|
g_object_notify_by_pspec (G_OBJECT (property), properties[PROP_I18N_COMMENT]);
|
|
}
|
|
|
|
G_CONST_RETURN gchar *
|
|
glade_property_i18n_get_comment (GladeProperty * property)
|
|
{
|
|
g_return_val_if_fail (GLADE_IS_PROPERTY (property), NULL);
|
|
return property->priv->i18n_comment;
|
|
}
|
|
|
|
void
|
|
glade_property_i18n_set_context (GladeProperty * property, const gchar * str)
|
|
{
|
|
g_return_if_fail (GLADE_IS_PROPERTY (property));
|
|
if (property->priv->i18n_context)
|
|
g_free (property->priv->i18n_context);
|
|
|
|
property->priv->i18n_context = g_strdup (str);
|
|
g_object_notify_by_pspec (G_OBJECT (property), properties[PROP_I18N_CONTEXT]);
|
|
}
|
|
|
|
G_CONST_RETURN gchar *
|
|
glade_property_i18n_get_context (GladeProperty * property)
|
|
{
|
|
g_return_val_if_fail (GLADE_IS_PROPERTY (property), NULL);
|
|
return property->priv->i18n_context;
|
|
}
|
|
|
|
void
|
|
glade_property_i18n_set_translatable (GladeProperty * property,
|
|
gboolean translatable)
|
|
{
|
|
g_return_if_fail (GLADE_IS_PROPERTY (property));
|
|
property->priv->i18n_translatable = translatable;
|
|
g_object_notify_by_pspec (G_OBJECT (property), properties[PROP_I18N_TRANSLATABLE]);
|
|
}
|
|
|
|
gboolean
|
|
glade_property_i18n_get_translatable (GladeProperty * property)
|
|
{
|
|
g_return_val_if_fail (GLADE_IS_PROPERTY (property), FALSE);
|
|
return property->priv->i18n_translatable;
|
|
}
|
|
|
|
void
|
|
glade_property_set_sensitive (GladeProperty * property,
|
|
gboolean sensitive, const gchar * reason)
|
|
{
|
|
g_return_if_fail (GLADE_IS_PROPERTY (property));
|
|
|
|
/* reason is only why we're disableing it */
|
|
if (sensitive == FALSE)
|
|
{
|
|
if (property->priv->insensitive_tooltip)
|
|
g_free (property->priv->insensitive_tooltip);
|
|
property->priv->insensitive_tooltip = g_strdup (reason);
|
|
}
|
|
|
|
if (property->priv->sensitive != sensitive)
|
|
{
|
|
property->priv->sensitive = sensitive;
|
|
|
|
/* Clear it */
|
|
if (sensitive)
|
|
property->priv->insensitive_tooltip =
|
|
(g_free (property->priv->insensitive_tooltip), NULL);
|
|
|
|
g_signal_emit (G_OBJECT (property),
|
|
glade_property_signals[TOOLTIP_CHANGED],
|
|
0,
|
|
glade_property_class_get_tooltip (property->priv->klass),
|
|
property->priv->insensitive_tooltip,
|
|
property->priv->support_warning);
|
|
}
|
|
g_object_notify_by_pspec (G_OBJECT (property), properties[PROP_SENSITIVE]);
|
|
}
|
|
|
|
G_CONST_RETURN gchar *
|
|
glade_propert_get_insensitive_tooltip (GladeProperty *property)
|
|
{
|
|
g_return_val_if_fail (GLADE_IS_PROPERTY (property), NULL);
|
|
|
|
return property->priv->insensitive_tooltip;
|
|
}
|
|
|
|
gboolean
|
|
glade_property_get_sensitive (GladeProperty * property)
|
|
{
|
|
g_return_val_if_fail (GLADE_IS_PROPERTY (property), FALSE);
|
|
return property->priv->sensitive;
|
|
}
|
|
|
|
void
|
|
glade_property_set_support_warning (GladeProperty * property,
|
|
gboolean disable, const gchar * reason)
|
|
{
|
|
g_return_if_fail (GLADE_IS_PROPERTY (property));
|
|
|
|
if (property->priv->support_warning)
|
|
g_free (property->priv->support_warning);
|
|
property->priv->support_warning = g_strdup (reason);
|
|
|
|
property->priv->support_disabled = disable;
|
|
|
|
g_signal_emit (G_OBJECT (property),
|
|
glade_property_signals[TOOLTIP_CHANGED],
|
|
0,
|
|
glade_property_class_get_tooltip (property->priv->klass),
|
|
property->priv->insensitive_tooltip,
|
|
property->priv->support_warning);
|
|
|
|
glade_property_fix_state (property);
|
|
}
|
|
|
|
G_CONST_RETURN gchar *
|
|
glade_property_get_support_warning (GladeProperty *property)
|
|
{
|
|
g_return_val_if_fail (GLADE_IS_PROPERTY (property), NULL);
|
|
|
|
return property->priv->support_warning;
|
|
}
|
|
|
|
|
|
/**
|
|
* glade_property_set_save_always:
|
|
* @property: A #GladeProperty
|
|
* @setting: the value to set
|
|
*
|
|
* Sets whether this property should be special cased
|
|
* to always be saved regardless of its default value.
|
|
* (used for some special cases like properties
|
|
* that are assigned initial values in composite widgets
|
|
* or derived widget code).
|
|
*/
|
|
void
|
|
glade_property_set_save_always (GladeProperty * property, gboolean setting)
|
|
{
|
|
g_return_if_fail (GLADE_IS_PROPERTY (property));
|
|
|
|
property->priv->save_always = setting;
|
|
}
|
|
|
|
/**
|
|
* glade_property_get_save_always:
|
|
* @property: A #GladeProperty
|
|
*
|
|
* Returns: whether this property is special cased
|
|
* to always be saved regardless of its default value.
|
|
*/
|
|
gboolean
|
|
glade_property_get_save_always (GladeProperty * property)
|
|
{
|
|
g_return_val_if_fail (GLADE_IS_PROPERTY (property), FALSE);
|
|
|
|
return property->priv->save_always;
|
|
}
|
|
|
|
void
|
|
glade_property_set_enabled (GladeProperty * property, gboolean enabled)
|
|
{
|
|
g_return_if_fail (GLADE_IS_PROPERTY (property));
|
|
|
|
property->priv->enabled = enabled;
|
|
if (enabled)
|
|
glade_property_sync (property);
|
|
|
|
glade_property_fix_state (property);
|
|
|
|
g_object_notify_by_pspec (G_OBJECT (property), properties[PROP_ENABLED]);
|
|
}
|
|
|
|
gboolean
|
|
glade_property_get_enabled (GladeProperty * property)
|
|
{
|
|
g_return_val_if_fail (GLADE_IS_PROPERTY (property), FALSE);
|
|
return property->priv->enabled;
|
|
}
|
|
|
|
gchar *
|
|
glade_property_make_string (GladeProperty *property)
|
|
{
|
|
g_return_val_if_fail (GLADE_IS_PROPERTY (property), NULL);
|
|
|
|
return glade_property_class_make_string_from_gvalue (property->priv->klass,
|
|
property->priv->value);
|
|
}
|
|
|
|
void
|
|
glade_property_set_widget (GladeProperty *property,
|
|
GladeWidget *widget)
|
|
{
|
|
g_return_if_fail (GLADE_IS_PROPERTY (property));
|
|
|
|
property->priv->widget = widget;
|
|
}
|
|
|
|
GladeWidget *
|
|
glade_property_get_widget (GladeProperty *property)
|
|
{
|
|
g_return_val_if_fail (GLADE_IS_PROPERTY (property), NULL);
|
|
|
|
return property->priv->widget;
|
|
}
|
|
|
|
GValue *
|
|
glade_property_inline_value (GladeProperty *property)
|
|
{
|
|
g_return_val_if_fail (GLADE_IS_PROPERTY (property), NULL);
|
|
|
|
return property->priv->value;
|
|
}
|
|
|
|
GladePropertyState
|
|
glade_property_get_state (GladeProperty *property)
|
|
{
|
|
g_return_val_if_fail (GLADE_IS_PROPERTY (property), 0);
|
|
|
|
return property->priv->state;
|
|
}
|
|
|
|
|
|
static gint glade_property_su_stack = 0;
|
|
|
|
void
|
|
glade_property_push_superuser (void)
|
|
{
|
|
glade_property_su_stack++;
|
|
}
|
|
|
|
void
|
|
glade_property_pop_superuser (void)
|
|
{
|
|
if (--glade_property_su_stack < 0)
|
|
{
|
|
g_critical ("Bug: property super user stack is corrupt.\n");
|
|
}
|
|
}
|
|
|
|
gboolean
|
|
glade_property_superuser (void)
|
|
{
|
|
return glade_property_su_stack > 0;
|
|
}
|