Updated list

* TODO: Updated list

* doc/glade-sections.txt: Updated list

* doc/tmpl/*: updated templates from source

* src/glade-builtins.[ch]: Implemented GladeParamSpecObjects and
  GLADE_TYPE_GLIST boxed type (intended use for AtkRelation properties).

* src/glade-command.c, src/glade-gtk.c: Fixed refcounting for placeholders.
  (updated code for glade_widget_new () also)

* src/glade-project-window.c: Fixed parenthesis in complex statement.

* src/glade-property-class.[ch]:
  o Added support for atk property detection & GladeParamSpecObjects.
  o Added some more logic that belonged here and was in glade-widget-class.c
  o Fixed "make gvalue from object" logic to not leak a reference to a pixbuf
    (it doesnt crash with pixbuf manipulation... not sure if we dont leak pixbufs
    though).

* src/glade-property.c: Simplified code (and fixed limitation of optional properties
  to integer inputs... now any property can be optional).
  Added implicit case to ignore atk_properties

* src/glade-widget-class.c: Deffered some logic to glade-property-class and simplified
  code; also added support for atk properties.
  ATK: Disabled for now, not completely implemented... needs save support in glade-property
  and edit support in GladeEditorProperty... just needed to sync CVS for all the other
	  relevent work.

* src/glade-widget.[ch]: glade_widget_new () takes a boolean query arg now

* src/glade-xml-utils.[ch]: now has glade_xml_load_sym_from_node()
  (it makes sence here because we have access to the xml node structs; so we
  can debug around here a little easier).

* src/glade-editor-property.c: Added prelimenary support for GladeParamSpecObjects
  (readonly view of glade_widget_class_make_string_from_gvalue() ).

* src/glade-fixed-manager.c: Adjusted caller to glade_widget_new().

* src/glade.h: added "atk-relation" tag definition.
This commit is contained in:
Tristan Van Berkom 2006-02-24 02:04:38 +00:00
parent 9d89751931
commit eb9d377790
23 changed files with 839 additions and 383 deletions

View File

@ -1,3 +1,49 @@
2006-02-23 Tristan Van Berkom <tvb@gnome.org>
* TODO: Updated list
* doc/glade-sections.txt: Updated list
* doc/tmpl/*: updated templates from source
* src/glade-builtins.[ch]: Implemented GladeParamSpecObjects and
GLADE_TYPE_GLIST boxed type (intended use for AtkRelation properties).
* src/glade-command.c, src/glade-gtk.c: Fixed refcounting for placeholders.
(updated code for glade_widget_new () also)
* src/glade-project-window.c: Fixed parenthesis in complex statement.
* src/glade-property-class.[ch]:
o Added support for atk property detection & GladeParamSpecObjects.
o Added some more logic that belonged here and was in glade-widget-class.c
o Fixed "make gvalue from object" logic to not leak a reference to a pixbuf
(it doesnt crash with pixbuf manipulation... not sure if we dont leak pixbufs
though).
* src/glade-property.c: Simplified code (and fixed limitation of optional properties
to integer inputs... now any property can be optional).
Added implicit case to ignore atk_properties
* src/glade-widget-class.c: Deffered some logic to glade-property-class and simplified
code; also added support for atk properties.
ATK: Disabled for now, not completely implemented... needs save support in glade-property
and edit support in GladeEditorProperty... just needed to sync CVS for all the other
relevent work.
* src/glade-widget.[ch]: glade_widget_new () takes a boolean query arg now
* src/glade-xml-utils.[ch]: now has glade_xml_load_sym_from_node()
(it makes sence here because we have access to the xml node structs; so we
can debug around here a little easier).
* src/glade-editor-property.c: Added prelimenary support for GladeParamSpecObjects
(readonly view of glade_widget_class_make_string_from_gvalue() ).
* src/glade-fixed-manager.c: Adjusted caller to glade_widget_new().
* src/glade.h: added "atk-relation" tag definition.
2006-02-21 Tristan Van Berkom <tvb@gnome.org>
* src/glade-editor.c: Packing GladeEditorProperties were being loaded

4
TODO
View File

@ -8,12 +8,12 @@ Tasks:
o Implement atk properties (parser already works)
o Toolbar editor / Popup menu editor ?
o Add / Implement gnome widget catalogs (bug 315601)
o Handled startup errors correctly (bug 331797)
o Implement accelerator keys (bug 331808)
Complex bugs:
=============
o Unify multiple property changes & dont unify default settings (bug 315600)
o Properties/undo stack glitches (bug 316900)
o GtkTable packing props should adjust placeholders (bug 325791)
o Selection bug with some widgets (properly streamlining events
on widgets in the glade runtime environment) (bug 327379)

View File

@ -327,7 +327,6 @@ glade_property_class_make_string_from_gvalue
glade_property_class_make_gvalue_from_vl
glade_property_class_set_vl_from_gvalue
glade_property_class_update_from_node
glade_property_class_make_string_from_flags
glade_property_class_get_displayable_value
glade_property_class_make_adjustment
glade_property_class_match

View File

@ -39,6 +39,8 @@ va_lists etc (back and forth).
@construct_only:
@common:
@packing:
@atk_property:
@atk_relation:
@translatable:
@visible_lines:
@save:
@ -184,17 +186,6 @@ va_lists etc (back and forth).
@Returns:
<!-- ##### FUNCTION glade_property_class_make_string_from_flags ##### -->
<para>
</para>
@class:
@fvals:
@displayables:
@Returns:
<!-- ##### FUNCTION glade_property_class_get_displayable_value ##### -->
<para>

View File

@ -93,6 +93,7 @@ convenience api for getting and setting properties (mostly from the plugin).
@parent:
@klass:
@project:
@query:
@Returns:

View File

@ -31,8 +31,19 @@
#include <glib/gi18n-lib.h>
#include "glade-builtins.h"
/* Generate the GType dynamicly from the gtk stock engine
*/
struct _GladeParamSpecObjects {
GParamSpec parent_instance;
GType type;
GPtrArray *objects;
};
/************************************************************
* Auto-generate the enum type for stock properties *
************************************************************/
GType
glade_standard_stock_get_type (void)
{
@ -86,62 +97,190 @@ glade_standard_stock_spec (void)
0, G_PARAM_READWRITE);
}
/****************************************************************
* Built-in GladeParamSpecObjects for object array properties *
****************************************************************/
GType
glade_glist_get_type (void)
{
static GType type_id = 0;
if (!type_id)
type_id = g_boxed_type_register_static ("GladeGList",
(GBoxedCopyFunc) g_list_copy,
(GBoxedFreeFunc) g_list_free);
return type_id;
}
static void
param_objects_init (GParamSpec *pspec)
{
GladeParamSpecObjects *ospec = GLADE_PARAM_SPEC_OBJECTS (pspec);
ospec->type = G_TYPE_OBJECT;
}
static void
param_objects_set_default (GParamSpec *pspec,
GValue *value)
{
if (value->data[0].v_pointer != NULL)
{
g_free (value->data[0].v_pointer);
}
value->data[0].v_pointer = NULL;
}
static gboolean
param_objects_validate (GParamSpec *pspec,
GValue *value)
{
GladeParamSpecObjects *ospec = GLADE_PARAM_SPEC_OBJECTS (pspec);
GList *objects, *list, *toremove = NULL;
GObject *object;
objects = value->data[0].v_pointer;
for (list = objects; list; list = list->next)
{
object = list->data;
if (!g_value_type_compatible (G_OBJECT_TYPE (object), ospec->type))
{
toremove = g_list_prepend (toremove, object);
}
}
for (list = toremove; list; list = list->next)
{
object = list->data;
objects = g_list_remove (objects, object);
}
if (toremove) g_list_free (toremove);
value->data[0].v_pointer = objects;
return toremove != NULL;
}
static gint
param_objects_values_cmp (GParamSpec *pspec,
const GValue *value1,
const GValue *value2)
{
guint8 *p1 = value1->data[0].v_pointer;
guint8 *p2 = value2->data[0].v_pointer;
/* not much to compare here, try to at least provide stable lesser/greater result */
return p1 < p2 ? -1 : p1 > p2;
}
GType
glade_param_objects_get_type (void)
{
static GType objects_type = 0;
if (objects_type == 0)
{
static /* const */ GParamSpecTypeInfo pspec_info = {
sizeof (GParamSpecObject), /* instance_size */
16, /* n_preallocs */
param_objects_init, /* instance_init */
0xdeadbeef, /* value_type, assigned further down */
NULL, /* finalize */
param_objects_set_default, /* value_set_default */
param_objects_validate, /* value_validate */
param_objects_values_cmp, /* values_cmp */
};
pspec_info.value_type = GLADE_TYPE_GLIST;
objects_type = g_param_type_register_static
("GladeParamObjects", &pspec_info);
}
return objects_type;
}
GParamSpec *
glade_param_spec_objects (const gchar *name,
const gchar *nick,
const gchar *blurb,
GType accepted_type,
GParamFlags flags)
{
GladeParamSpecObjects *pspec;
pspec = g_param_spec_internal (GLADE_TYPE_PARAM_OBJECTS,
name, nick, blurb, flags);
pspec->type = accepted_type;
return G_PARAM_SPEC (pspec);
}
void
glade_param_spec_objects_set_type (GladeParamSpecObjects *pspec,
GType type)
{
pspec->type = type;
}
/* This was developed for the purpose of holding a list
* of 'targets' in an AtkRelation (we are setting it up
* as a property)
*/
GParamSpec *
glade_standard_objects_spec (void)
{
return glade_param_spec_objects ("objects", _("Objects"),
_("A list of objects"),
G_TYPE_OBJECT,
G_PARAM_READWRITE);
}
/****************************************************************
* Basic types follow *
****************************************************************/
GParamSpec *
glade_standard_int_spec (void)
{
static GParamSpec *int_spec = NULL;
if (!int_spec)
int_spec = g_param_spec_int ("int", _("Integer"),
_("An integer value"),
0, G_MAXINT,
0, G_PARAM_READWRITE);
return int_spec;
return g_param_spec_int ("int", _("Integer"),
_("An integer value"),
0, G_MAXINT,
0, G_PARAM_READWRITE);
}
GParamSpec *
glade_standard_string_spec (void)
{
static GParamSpec *str_spec = NULL;
if (!str_spec)
str_spec = g_param_spec_string ("string", _("String"),
_("An entry"), "",
G_PARAM_READWRITE);
return str_spec;
return g_param_spec_string ("string", _("String"),
_("An entry"), "",
G_PARAM_READWRITE);
}
GParamSpec *
glade_standard_strv_spec (void)
{
static GParamSpec *strv_spec = NULL;
if (!strv_spec)
strv_spec = g_param_spec_boxed ("strv", _("Strv"),
_("String array"),
G_TYPE_STRV,
G_PARAM_READWRITE);
return strv_spec;
return g_param_spec_boxed ("strv", _("Strv"),
_("String array"),
G_TYPE_STRV,
G_PARAM_READWRITE);
}
GParamSpec *
glade_standard_float_spec (void)
{
static GParamSpec *float_spec = NULL;
if (!float_spec)
float_spec = g_param_spec_float ("float", _("Float"),
_("A floating point entry"),
0.0F, G_MAXFLOAT, 0.0F,
G_PARAM_READWRITE);
return float_spec;
return g_param_spec_float ("float", _("Float"),
_("A floating point entry"),
0.0F, G_MAXFLOAT, 0.0F,
G_PARAM_READWRITE);
}
GParamSpec *
glade_standard_boolean_spec (void)
{
static GParamSpec *boolean_spec = NULL;
if (!boolean_spec)
boolean_spec = g_param_spec_boolean ("boolean", _("Boolean"),
_("A boolean value"), FALSE,
G_PARAM_READWRITE);
return boolean_spec;
return g_param_spec_boolean ("boolean", _("Boolean"),
_("A boolean value"), FALSE,
G_PARAM_READWRITE);
}

View File

@ -11,13 +11,47 @@ G_BEGIN_DECLS
LIBGLADEUI_API GType glade_standard_stock_get_type (void);
#define GLADE_IS_PARAM_SPEC_STOCK(pspec) (G_TYPE_CHECK_INSTANCE_TYPE ((pspec), GLADE_TYPE_STOCK))
LIBGLADEUI_API GParamSpec *glade_standard_stock_spec (void);
LIBGLADEUI_API GParamSpec *glade_standard_int_spec (void);
LIBGLADEUI_API GParamSpec *glade_standard_string_spec (void);
LIBGLADEUI_API GParamSpec *glade_standard_strv_spec (void);
LIBGLADEUI_API GParamSpec *glade_standard_float_spec (void);
LIBGLADEUI_API GParamSpec *glade_standard_boolean_spec (void);
#define GLADE_IS_PARAM_SPEC_STOCK(pspec) \
(G_TYPE_CHECK_INSTANCE_TYPE ((pspec), GLADE_TYPE_STOCK))
typedef struct _GladeParamSpecObjects GladeParamSpecObjects;
#define GLADE_TYPE_GLIST (glade_glist_get_type())
#define GLADE_TYPE_PARAM_OBJECTS (glade_param_objects_get_type())
#define GLADE_IS_PARAM_SPEC_OBJECTS(pspec) \
(G_TYPE_CHECK_INSTANCE_TYPE ((pspec), \
GLADE_TYPE_PARAM_OBJECTS))
#define GLADE_PARAM_SPEC_OBJECTS(pspec) \
(G_TYPE_CHECK_INSTANCE_CAST ((pspec), \
GLADE_TYPE_PARAM_OBJECTS, GladeParamSpecObjects))
LIBGLADEUI_API GType glade_glist_get_type (void) G_GNUC_CONST;
LIBGLADEUI_API GType glade_param_objects_get_type (void) G_GNUC_CONST;
LIBGLADEUI_API GParamSpec *glade_param_spec_objects (const gchar *name,
const gchar *nick,
const gchar *blurb,
GType accepted_type,
GParamFlags flags);
LIBGLADEUI_API void glade_param_spec_objects_set_type (GladeParamSpecObjects *pspec,
GType type);
LIBGLADEUI_API GParamSpec **glade_list_atk_relations (GType owner_type,
guint *n_specs);
LIBGLADEUI_API GParamSpec *glade_standard_objects_spec (void);
LIBGLADEUI_API GParamSpec *glade_standard_stock_spec (void);
LIBGLADEUI_API GParamSpec *glade_standard_int_spec (void);
LIBGLADEUI_API GParamSpec *glade_standard_string_spec (void);
LIBGLADEUI_API GParamSpec *glade_standard_strv_spec (void);
LIBGLADEUI_API GParamSpec *glade_standard_float_spec (void);
LIBGLADEUI_API GParamSpec *glade_standard_boolean_spec (void);
G_END_DECLS

View File

@ -43,6 +43,13 @@
#include "glade-app.h"
#include "glade-fixed-manager.h"
/* Concerning placeholders: we do not hold any reference to placeholders,
* placeholders that are supplied by the backend are not reffed, placeholders
* that are created by glade-command are temporarily owned by glade-command
* untill they are added to a container; in which case it belongs to GTK+
* and the backend (but I prefer to think of it as the backend).
*/
typedef struct {
GladeWidget *widget;
GladeWidget *parent;
@ -796,6 +803,18 @@ glade_command_placeholder_destroyed (GtkObject *object, CommandData *cdata)
}
}
static void
glade_command_placeholder_connect (CommandData *cdata,
GladePlaceholder *placeholder)
{
g_assert (cdata && cdata->placeholder == NULL);
cdata->placeholder = placeholder;
cdata->handler_id = g_signal_connect
(placeholder, "destroy",
G_CALLBACK (glade_command_placeholder_destroyed), cdata);
}
static gboolean
glade_command_create_execute (GladeCommandCreateDelete *me)
{
@ -873,17 +892,9 @@ glade_command_delete_execute (GladeCommandCreateDelete *me)
if (cdata->parent)
{
if (cdata->placeholder)
{
glade_widget_replace
(cdata->parent, cdata->widget->object,
G_OBJECT (cdata->placeholder));
if (cdata->handler_id == 0)
cdata->handler_id = g_signal_connect (
cdata->placeholder, "destroy",
G_CALLBACK (glade_command_placeholder_destroyed),
cdata);
}
else if (cdata->parent->manager != NULL)
glade_fixed_manager_remove_child
(cdata->parent->manager, cdata->widget);
@ -955,7 +966,8 @@ glade_command_create_delete_finalize (GObject *obj)
if (cdata->handler_id)
g_signal_handler_disconnect (cdata->placeholder,
cdata->handler_id);
g_object_unref (cdata->placeholder);
if (GTK_OBJECT_FLOATING (cdata->placeholder))
gtk_widget_destroy (GTK_WIDGET (cdata->placeholder));
}
if (cdata->widget)
@ -1031,10 +1043,8 @@ glade_command_delete (GList *widgets)
glade_util_gtkcontainer_relation
(cdata->parent, cdata->widget))
{
cdata->placeholder =
GLADE_PLACEHOLDER (glade_placeholder_new ());
g_object_ref (G_OBJECT (cdata->placeholder));
gtk_object_sink (GTK_OBJECT (cdata->placeholder));
glade_command_placeholder_connect
(cdata, GLADE_PLACEHOLDER (glade_placeholder_new ()));
}
me->widgets = g_list_prepend (me->widgets, cdata);
}
@ -1089,15 +1099,15 @@ glade_command_create (GladeWidgetClass *class,
cdata = g_new0 (CommandData, 1);
cdata->parent = parent;
if ((cdata->placeholder = placeholder) != NULL)
g_object_ref (G_OBJECT (placeholder));
glade_command_placeholder_connect (cdata, placeholder);
me->widgets = g_list_append (me->widgets, cdata);
if (parent && parent->manager != NULL)
widget = glade_fixed_manager_create_child (parent->manager, class);
else
widget = glade_widget_new (parent, class, project);
widget = glade_widget_new (parent, class, project, TRUE);
/* widget may be null, e.g. the user clicked cancel on a query */
if ((cdata->widget = widget) == NULL)
@ -1144,7 +1154,7 @@ typedef struct {
GList *widgets;
GladeCutCopyPasteType type;
gboolean from_clipboard;
gboolean initial_paste;
gboolean props_recorded;
} GladeCommandCutCopyPaste;
@ -1184,11 +1194,9 @@ glade_command_paste_execute (GladeCommandCutCopyPaste *me)
G_OBJECT (cdata->placeholder),
cdata->widget->object);
else if (cdata->parent->manager != NULL)
{
/* Paste at mouse position only once */
glade_fixed_manager_add_child (cdata->parent->manager, cdata->widget,
me->initial_paste == FALSE);
}
me->props_recorded == FALSE);
else
{
glade_widget_set_parent (cdata->widget,
@ -1214,9 +1222,12 @@ glade_command_paste_execute (GladeCommandCutCopyPaste *me)
}
if (me->initial_paste == FALSE)
if (me->props_recorded == FALSE)
{
// Save the packing properties after the initial paste.
/* Save the packing properties after the initial paste.
* (this will be the defaults returned by the container
* implementation after initially adding them).
*/
g_assert (cdata->pack_props == NULL);
for (l = cdata->widget->packing_properties; l; l = l->next)
cdata->pack_props =
@ -1225,8 +1236,10 @@ glade_command_paste_execute (GladeCommandCutCopyPaste *me)
cdata->widget));
}
me->initial_paste = TRUE; // Mark it initialy pasted
/* Mark the properties as recorded
*/
me->props_recorded = TRUE;
}
@ -1271,18 +1284,10 @@ glade_command_cut_execute (GladeCommandCutCopyPaste *me)
if (cdata->parent)
{
if (cdata->placeholder)
{
glade_widget_replace
(cdata->parent,
cdata->widget->object,
G_OBJECT (cdata->placeholder));
if (cdata->handler_id == 0)
cdata->handler_id = g_signal_connect (
cdata->placeholder, "destroy",
G_CALLBACK (glade_command_placeholder_destroyed),
cdata);
}
else if (cdata->parent->manager != NULL)
glade_fixed_manager_remove_child
(cdata->parent->manager, cdata->widget);
@ -1403,7 +1408,9 @@ glade_command_cut_copy_paste_finalize (GObject *obj)
if (cdata->handler_id)
g_signal_handler_disconnect (cdata->placeholder,
cdata->handler_id);
g_object_unref (cdata->placeholder);
if (GTK_OBJECT_FLOATING (cdata->placeholder))
gtk_widget_destroy (GTK_WIDGET (cdata->placeholder));
}
if (cdata->pack_props)
{
@ -1505,24 +1512,23 @@ glade_command_cut_copy_paste_common (GList *widgets,
g_critical ("Parentless non GtkWindow widget in Paste");
/* Placeholder */
if (type == GLADE_CUT)
{
if (cdata->parent && cdata->parent->manager == NULL &&
glade_util_gtkcontainer_relation
(cdata->parent, cdata->widget))
{
cdata->placeholder = GLADE_PLACEHOLDER
(glade_placeholder_new ());
g_object_ref (G_OBJECT (cdata->placeholder));
gtk_object_sink (GTK_OBJECT (cdata->placeholder));
glade_command_placeholder_connect
(cdata, GLADE_PLACEHOLDER (glade_placeholder_new ()));
}
else if (placeholder != NULL)
cdata->placeholder = g_object_ref (placeholder);
glade_command_placeholder_connect (cdata, placeholder);
}
else if (type == GLADE_PASTE && placeholder != NULL &&
g_list_length (widgets) == 1)
{
cdata->placeholder = g_object_ref (placeholder);
glade_command_placeholder_connect (cdata, placeholder);
}
else if (type == GLADE_PASTE && cdata->parent &&
cdata->parent->manager == NULL &&
@ -1540,7 +1546,8 @@ glade_command_cut_copy_paste_common (GList *widgets,
g_list_find (placeholders, child) == NULL)
{
placeholders = g_list_append (placeholders, child);
cdata->placeholder = g_object_ref (child);
glade_command_placeholder_connect
(cdata, GLADE_PLACEHOLDER (child));
break;
}
}
@ -1553,6 +1560,10 @@ glade_command_cut_copy_paste_common (GList *widgets,
*/
if (type == GLADE_CUT)
{
/* We dont want the paste mechanism to overwrite our
* packing props so we have to mark them "recorded"
*/
me->props_recorded = TRUE;
for (l = cdata->widget->packing_properties; l; l = l->next)
cdata->pack_props =
g_list_prepend (cdata->pack_props,
@ -1571,11 +1582,6 @@ glade_command_cut_copy_paste_common (GList *widgets,
me->widgets = g_list_prepend (me->widgets, cdata);
}
if (type == GLADE_CUT)
me->initial_paste = TRUE;
else
me->initial_paste = FALSE;
glade_command_check_group (GLADE_COMMAND (me));
/*

View File

@ -2250,6 +2250,77 @@ glade_eprop_object_create_input (GladeEditorProperty *eprop)
}
/*******************************************************************************
GladeEditorPropertyObjectsClass
*******************************************************************************/
typedef struct {
GladeEditorProperty parent_instance;
GtkWidget *entry;
} GladeEPropObjects;
GLADE_MAKE_EPROP (GladeEPropObjects, glade_eprop_objects)
#define GLADE_TYPE_EPROP_OBJECTS (glade_eprop_objects_get_type())
#define GLADE_EPROP_OBJECTS(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GLADE_TYPE_EPROP_OBJECTS, GladeEPropObjects))
#define GLADE_EPROP_OBJECTS_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GLADE_TYPE_EPROP_OBJECTS, GladeEPropObjectsClass))
#define GLADE_IS_EPROP_OBJECTS(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GLADE_TYPE_EPROP_OBJECTS))
#define GLADE_IS_EPROP_OBJECTS_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GLADE_TYPE_EPROP_OBJECTS))
#define GLADE_EPROP_OBJECTS_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), GLADE_EPROP_OBJECTS, GladeEPropObjectsClass))
static void
glade_eprop_objects_finalize (GObject *object)
{
/* Chain up */
G_OBJECT_CLASS (editor_property_class)->finalize (object);
}
static void
glade_eprop_objects_load (GladeEditorProperty *eprop, GladeProperty *property)
{
GladeEPropObjects *eprop_objects = GLADE_EPROP_OBJECTS (eprop);
gchar *obj_name;
/* Chain up first */
editor_property_class->load (eprop, property);
if (property == NULL) return;
if ((obj_name = glade_property_class_make_string_from_gvalue
(eprop->class, property->value)) != NULL)
{
gtk_entry_set_text (GTK_ENTRY (eprop_objects->entry), obj_name);
g_free (obj_name);
}
else
gtk_entry_set_text (GTK_ENTRY (eprop_objects->entry), "");
}
static GtkWidget *
glade_eprop_objects_create_input (GladeEditorProperty *eprop)
{
GladeEPropObjects *eprop_objects = GLADE_EPROP_OBJECTS (eprop);
GtkWidget *hbox;
GtkWidget *button;
hbox = gtk_hbox_new (FALSE, 0);
eprop_objects->entry = gtk_entry_new ();
gtk_entry_set_editable (GTK_ENTRY (eprop_objects->entry), FALSE);
gtk_widget_show (eprop_objects->entry);
gtk_box_pack_start (GTK_BOX (hbox), eprop_objects->entry, TRUE, TRUE, 0);
button = gtk_button_new_with_label ("...");
gtk_widget_show (button);
gtk_box_pack_start (GTK_BOX (hbox), button, FALSE, FALSE, 0);
/* g_signal_connect (G_OBJECTS (button), "clicked", */
/* G_CALLBACK (glade_eprop_objects_show_dialog), */
/* eprop); */
return hbox;
}
/*******************************************************************************
Misc static stuff
*******************************************************************************/
@ -2292,6 +2363,8 @@ glade_editor_property_type (GParamSpec *pspec)
else
type = GLADE_TYPE_EPROP_OBJECT;
}
else if (GLADE_IS_PARAM_SPEC_OBJECTS(pspec))
type = GLADE_TYPE_EPROP_OBJECTS;
return type;
}
@ -2320,8 +2393,11 @@ glade_editor_property_new (GladePropertyClass *class,
* GladePropertyClass.
*/
if ((type = glade_editor_property_type (class->pspec)) == 0)
g_error ("%s : type %s not implemented (%s)\n", G_GNUC_FUNCTION,
class->name, g_type_name (class->pspec->value_type));
g_error ("%s : pspec '%s' type '%s' not implemented (%s)\n",
G_GNUC_PRETTY_FUNCTION,
class->name,
g_type_name (G_PARAM_SPEC_TYPE (class->pspec)),
g_type_name (class->pspec->value_type));
/* special case for resource specs which are hand specified in the catalog. */
if (class->resource) type = GLADE_TYPE_EPROP_RESOURCE;

View File

@ -367,7 +367,7 @@ glade_fixed_manager_create_child_impl (GladeFixedManager *manager,
GladeWidget *gwidget =
glade_widget_new (manager->container,
wclass,
manager->container->project);
manager->container->project, TRUE);
return gwidget;
}

View File

@ -611,7 +611,7 @@ glade_gtk_button_ensure_glabel (GtkWidget *button)
{
wclass = glade_widget_class_get_by_type (GTK_TYPE_LABEL);
glabel = glade_widget_new (gbutton, wclass,
glade_widget_get_project (gbutton));
glade_widget_get_project (gbutton), FALSE);
glade_widget_property_set
(glabel, "label", gbutton->widget_class->generic_name);
@ -1143,7 +1143,7 @@ glade_gtk_frame_create_idle (gpointer data)
{
wclass = glade_widget_class_get_by_type (GTK_TYPE_LABEL);
glabel = glade_widget_new (gframe, wclass,
glade_widget_get_project (gframe));
glade_widget_get_project (gframe), FALSE);
if (GTK_IS_ASPECT_FRAME (frame))
glade_widget_property_set (glabel, "label", "aspect frame");
@ -1178,7 +1178,7 @@ glade_gtk_expander_create_idle (gpointer data)
{
wclass = glade_widget_class_get_by_type (GTK_TYPE_LABEL);
glabel = glade_widget_new (gexpander, wclass,
glade_widget_get_project (gexpander));
glade_widget_get_project (gexpander), FALSE);
glade_widget_property_set (glabel, "label", "expander");
@ -1475,6 +1475,32 @@ glade_gtk_container_replace_child (GtkWidget *container,
g_free (value);
}
void GLADEGTK_API
glade_gtk_container_add_child (GtkWidget *container,
GtkWidget *child)
{
/* Get a placeholder out of the way before adding the child if its a GtkBin
*/
if (GTK_IS_BIN (container) && GTK_BIN (container)->child != NULL &&
GLADE_IS_PLACEHOLDER (GTK_BIN (container)->child))
gtk_container_remove (GTK_CONTAINER (container), GTK_BIN (container)->child);
gtk_container_add (GTK_CONTAINER (container), child);
}
void GLADEGTK_API
glade_gtk_container_remove_child (GtkWidget *container,
GtkWidget *child)
{
gtk_container_remove (GTK_CONTAINER (container), child);
/* If this is the last one, add a placeholder by default.
*/
if (gtk_container_get_children (GTK_CONTAINER (container)) == NULL)
gtk_container_add (GTK_CONTAINER (container), glade_placeholder_new ());
}
void GLADEGTK_API
glade_gtk_notebook_replace_child (GtkWidget *container,
GtkWidget *current,
@ -1813,7 +1839,7 @@ glade_gtk_table_widget_exceeds_bounds (GtkTable *table, gint n_rows, gint n_cols
static void
glade_gtk_table_refresh_placeholders (GtkTable *table)
{
GList *list;
GList *list, *toremove = NULL;
gint i, j;
for (list = table->children; list && list->data; list = list->next)
@ -1834,12 +1860,18 @@ glade_gtk_table_refresh_placeholders (GtkTable *table)
if (glade_gtk_table_has_child (table, TRUE,
left_attach, top_attach))
gtk_widget_hide (child->widget);
else
gtk_widget_show (child->widget);
toremove = g_list_prepend (toremove, child->widget);
}
}
if (toremove)
{
for (list = toremove; list; list = list->next)
gtk_container_remove (GTK_CONTAINER (table),
GTK_WIDGET (list->data));
g_list_free (toremove);
}
for (i = 0; i < table->ncols; i++)
for (j = 0; j < table->nrows; j++)
if (glade_gtk_table_has_child (table, FALSE, i, j) == FALSE)
@ -2540,7 +2572,7 @@ glade_gtk_menu_bar_append_new_submenu (GladeWidget *parent, GladeProject *projec
if (submenu_class == NULL)
submenu_class = glade_widget_class_get_by_type (GTK_TYPE_MENU);
gsubmenu = glade_widget_new (parent, submenu_class, project);
gsubmenu = glade_widget_new (parent, submenu_class, project, FALSE);
glade_widget_class_container_add (glade_widget_get_class (parent),
glade_widget_get_object (parent),
@ -2569,7 +2601,7 @@ glade_gtk_menu_bar_append_new_item (GladeWidget *parent,
gitem = glade_widget_new (parent,
(use_stock) ? image_item_class : item_class,
project);
project, FALSE);
glade_widget_property_set (gitem, "use-underline", TRUE);
if (use_stock)

View File

@ -761,9 +761,9 @@ gpw_hijack_editor_key_press (GtkWidget *editor_win,
{
if (event->keyval == GDK_Delete || /* Filter Delete from accelerator keys */
((event->state & GDK_CONTROL_MASK) && /* CNTL keys... */
(event->keyval == GDK_c || event->keyval == GDK_C) || /* CNTL-C (copy) */
(event->keyval == GDK_x || event->keyval == GDK_X) || /* CNTL-X (cut) */
(event->keyval == GDK_v || event->keyval == GDK_V))) /* CNTL-V (paste) */
((event->keyval == GDK_c || event->keyval == GDK_C) || /* CNTL-C (copy) */
(event->keyval == GDK_x || event->keyval == GDK_X) || /* CNTL-X (cut) */
(event->keyval == GDK_v || event->keyval == GDK_V)))) /* CNTL-V (paste) */
{
return gtk_widget_event (GTK_WINDOW (editor_win)->focus_widget,
(GdkEvent *)event);

View File

@ -59,7 +59,7 @@ glade_property_class_new (void)
property_class->displayable_values = NULL;
property_class->query = FALSE;
property_class->optional = FALSE;
property_class->optional_default = TRUE;
property_class->optional_default = FALSE;
property_class->common = FALSE;
property_class->packing = FALSE;
property_class->is_modified = FALSE;
@ -70,7 +70,9 @@ glade_property_class_new (void)
property_class->save = TRUE;
property_class->ignore = FALSE;
property_class->resource = FALSE;
property_class->translatable = TRUE;
property_class->translatable = FALSE;
property_class->atk_property = FALSE;
property_class->atk_relation = FALSE;
return property_class;
}
@ -236,17 +238,7 @@ glade_property_class_make_string_from_enum (GType etype, gint eval)
return string;
}
/**
* glade_property_class_make_string_from_flags:
* @class: A GFlagsClass property class.
* @fvals: The flags to include in the string.
* @displayables: if TRUE it will try to use diplayable values.
*
* Create a string with the flags wich are set in @fvals.
*
* Returns: a newly allocated string.
*/
gchar *
static gchar *
glade_property_class_make_string_from_flags (GladePropertyClass *class, guint fvals, gboolean displayables)
{
GFlagsClass *fclass;
@ -281,21 +273,73 @@ glade_property_class_make_string_from_flags (GladePropertyClass *class, guint fv
return retval;
}
static gchar *
glade_property_class_make_string_from_object (GladePropertyClass *property_class,
GObject *object)
{
GladeWidget *gwidget;
gchar *string = NULL, *filename;
if (!object) return NULL;
if (property_class->pspec->value_type == GDK_TYPE_PIXBUF)
{
if ((filename = g_object_get_data (object, "GladeFileName")) != NULL)
string = g_path_get_basename (filename);
}
else if ((gwidget = glade_widget_get_from_gobject (object)) != NULL)
string = g_strdup (gwidget->name);
else
g_critical ("Object type property refers to an object "
"outside the project");
return string;
}
static gchar *
glade_property_class_make_string_from_objects (GladePropertyClass *property_class,
GList *objects)
{
GObject *object;
GList *list;
gchar *string = NULL, *obj_str, *tmp;
#define GPC_OBJECT_DELIMITER ", "
for (list = objects; list; list = list->next)
{
object = list->data;
obj_str = glade_property_class_make_string_from_object
(property_class, object);
if (string == NULL)
string = obj_str;
else if (obj_str != NULL)
{
tmp = g_strdup_printf ("%s%s%s", string, GPC_OBJECT_DELIMITER, obj_str);
string = (g_free (string), tmp);
g_free (obj_str);
}
}
return string;
}
/**
* glade_property_class_make_string_from_gvalue:
* @property_class:
* @value:
* @property_class: A #GladePropertyClass
* @value: A #GValue
*
* TODO: write me
*
* Returns:
* Returns: A newly allocated string representation of @value
*/
gchar *
glade_property_class_make_string_from_gvalue (GladePropertyClass *property_class,
const GValue *value)
{
gchar *string = NULL, **strv;
GObject *object;
GdkColor *color;
GList *objects;
if (G_IS_PARAM_SPEC_ENUM(property_class->pspec))
{
@ -365,27 +409,15 @@ glade_property_class_make_string_from_gvalue (GladePropertyClass *property_class
GLADE_TAG_TRUE : GLADE_TAG_FALSE);
else if (G_IS_PARAM_SPEC_OBJECT(property_class->pspec))
{
GObject *object = g_value_get_object (value);
if (property_class->pspec->value_type == GDK_TYPE_PIXBUF)
{
gchar *filename;
if (object && (filename = g_object_get_data
(object, "GladeFileName")) != NULL)
string = g_path_get_basename (filename);
}
else
{
GladeWidget *gwidget;
if (object)
{
if ((gwidget = glade_widget_get_from_gobject (object)) != NULL)
string = g_strdup (gwidget->name);
else
g_critical ("Object type property refers to an object outside the project");
}
}
object = g_value_get_object (value);
string = glade_property_class_make_string_from_object
(property_class, object);
}
else if (GLADE_IS_PARAM_SPEC_OBJECTS (property_class->pspec))
{
objects = g_value_get_boxed (value);
string = glade_property_class_make_string_from_objects
(property_class, objects);
}
else
g_critical ("Unsupported pspec type %s",
@ -395,9 +427,6 @@ glade_property_class_make_string_from_gvalue (GladePropertyClass *property_class
}
/* This is copied exactly from libglade. I've just renamed the function.
*
* TODO: Expose function from libglade and use the one in libglade (once
* Ivan Wongs libglade patch gets in...).
*/
static guint
glade_property_class_make_flags_from_string (GType type, const char *string)
@ -501,6 +530,67 @@ glade_property_class_make_enum_from_string (GType type, const char *string)
return ret;
}
static GObject *
glade_property_class_make_object_from_string (GladePropertyClass *property_class,
const gchar *string,
GladeProject *project)
{
GObject *object = NULL;
gchar *fullpath;
if (property_class->pspec->value_type == GDK_TYPE_PIXBUF && project)
{
GdkPixbuf *pixbuf;
if (string)
{
fullpath = glade_project_resource_fullpath (project, string);
if ((pixbuf = gdk_pixbuf_new_from_file
(fullpath, NULL)) != NULL)
{
g_object_set_data_full (G_OBJECT(pixbuf),
"GladeFileName",
g_strdup (string),
g_free);
object = G_OBJECT(pixbuf);
}
g_free (fullpath);
}
}
else
{
GladeWidget *gwidget;
if (string && (gwidget = glade_project_get_widget_by_name
(project, string)) != NULL)
object = gwidget->object;
}
return object;
}
static GList *
glade_property_class_make_objects_from_string (GladePropertyClass *property_class,
const gchar *string,
GladeProject *project)
{
GList *objects = NULL;
GObject *object;
gchar **split;
guint i;
if ((split = g_strsplit (string, GPC_OBJECT_DELIMITER, 0)) != NULL)
{
for (i = 0; split[i]; i++)
{
if ((object = glade_property_class_make_object_from_string
(property_class, split[i], project)) != NULL)
objects = g_list_prepend (objects, object);
}
g_strfreev (split);
}
return objects;
}
/**
* glade_property_class_make_gvalue_from_string:
@ -602,38 +692,15 @@ glade_property_class_make_gvalue_from_string (GladePropertyClass *property_class
}
else if (G_IS_PARAM_SPEC_OBJECT(property_class->pspec))
{
if (property_class->pspec->value_type == GDK_TYPE_PIXBUF && project)
{
GdkPixbuf *pixbuf;
if (string)
{
fullpath =
glade_project_resource_fullpath (project,
string);
if ((pixbuf = gdk_pixbuf_new_from_file
(fullpath, NULL)) != NULL)
{
g_object_set_data_full (G_OBJECT(pixbuf),
"GladeFileName",
g_strdup (string),
g_free);
g_value_take_object (value, G_OBJECT(pixbuf));
}
g_free (fullpath);
}
else
g_value_set_object (value, NULL);
}
else
{
GladeWidget *gwidget;
if (string && (gwidget = glade_project_get_widget_by_name
(project, string)) != NULL)
g_value_set_object (value, gwidget->object);
else
g_value_set_object (value, NULL);
}
GObject *object = glade_property_class_make_object_from_string
(property_class, string, project);
g_value_set_object (value, object);
}
else if (GLADE_IS_PARAM_SPEC_OBJECTS (property_class->pspec))
{
GList *objects = glade_property_class_make_objects_from_string
(property_class, string, project);
g_value_set_boxed (value, objects);
}
else
g_critical ("Unsupported pspec type %s",
@ -642,6 +709,15 @@ glade_property_class_make_gvalue_from_string (GladePropertyClass *property_class
return value;
}
/**
* glade_property_class_make_gvalue_from_vl:
* @property_class: A #GladePropertyClass
* @vl: a #va_list holding one argument of the correct type
* specified by @property_class
*
* Returns: A #GValue created based on the @property_class
* and a @vl arg of the correct type.
*/
GValue *
glade_property_class_make_gvalue_from_vl (GladePropertyClass *class,
va_list vl)
@ -695,6 +771,16 @@ glade_property_class_make_gvalue_from_vl (GladePropertyClass *class,
}
/**
* glade_property_class_set_vl_from_gvalue:
* @class: A #GladePropertyClass
* @value: A #GValue to set
* @vl: a #va_list holding one argument of the correct type
* specified by @class
*
*
* Sets @value from @vl based on @class criteria.
*/
void
glade_property_class_set_vl_from_gvalue (GladePropertyClass *class,
GValue *value,
@ -765,6 +851,10 @@ glade_property_class_new_from_spec (GParamSpec *spec)
property_class = glade_property_class_new ();
property_class->pspec = spec;
/* We only use the writable properties */
if ((spec->flags & G_PARAM_WRITABLE) == 0)
goto lblError;
/* Register only editable properties.
*/
@ -782,9 +872,22 @@ glade_property_class_new_from_spec (GParamSpec *spec)
g_param_spec_get_name (spec)) != NULL)
property_class->common = TRUE;
/* If its a child property of a GtkContainerClass derivative,
* it goes in "packing"
*/
if (g_object_class_find_property (gtk_widget_class,
g_param_spec_get_name (spec)) != NULL)
property_class->packing = TRUE;
/* Flag the construct only properties */
if (spec->flags & G_PARAM_CONSTRUCT_ONLY)
property_class->construct_only = TRUE;
if (!property_class->id || !property_class->name)
{
g_warning ("Failed to create property class from spec");
g_critical ("No name or id for "
"glade_property_class_new_from_spec, failed.");
goto lblError;
}
@ -792,6 +895,7 @@ glade_property_class_new_from_spec (GParamSpec *spec)
property_class->orig_def = glade_property_class_get_default_from_spec (spec);
property_class->def = glade_property_class_get_default_from_spec (spec);
g_type_class_unref (gtk_widget_class);
return property_class;
lblError:
@ -998,6 +1102,33 @@ glade_property_class_make_adjustment (GladePropertyClass *property_class)
GLADE_NUMERICAL_PAGE_SIZE);
}
static void
gpc_load_function (GladeXmlNode *node,
GModule *module,
const gchar *tagname,
gpointer *location)
{
GladeXmlNode *child = glade_xml_search_child (node, tagname);
if (child)
{
gchar *symbol_name = glade_xml_get_content (child);
if (!module)
{
g_warning ("Catalog specified symbol '%s' for tag '%s', "
"no module available to load it from !",
symbol_name, tagname);
g_free (symbol_name);
return;
}
if (!g_module_symbol(module, symbol_name, location))
g_warning ("Could not find %s in %s\n",
symbol_name, g_module_name (module));
g_free (symbol_name);
}
}
/**
* glade_property_class_update_from_node:
* @node: the property node
@ -1090,8 +1221,7 @@ glade_property_class_update_from_node (GladeXmlNode *node,
}
/* Get the default */
buff = glade_xml_get_property_string (node, GLADE_TAG_DEFAULT);
if (buff)
if ((buff = glade_xml_get_property_string (node, GLADE_TAG_DEFAULT)) != NULL)
{
if (class->def) {
g_value_unset (class->def);
@ -1102,16 +1232,14 @@ glade_property_class_update_from_node (GladeXmlNode *node,
}
/* If needed, update the name... */
buff = glade_xml_get_property_string (node, GLADE_TAG_NAME);
if (buff)
if ((buff = glade_xml_get_property_string (node, GLADE_TAG_NAME)) != NULL)
{
g_free (class->name);
class->name = g_strdup (dgettext (domain, buff));
}
/* ...and the tooltip */
buff = glade_xml_get_value_string (node, GLADE_TAG_TOOLTIP);
if (buff)
if ((buff = glade_xml_get_value_string (node, GLADE_TAG_TOOLTIP)) != NULL)
{
g_free (class->tooltip);
class->tooltip = g_strdup (dgettext (domain, buff));
@ -1147,15 +1275,14 @@ glade_property_class_update_from_node (GladeXmlNode *node,
glade_xml_get_value_int (node, GLADE_TAG_VISIBLE_LINES, &class->visible_lines);
/* Get the Parameters */
child = glade_xml_search_child (node, GLADE_TAG_PARAMETERS);
if (child)
if ((child = glade_xml_search_child (node, GLADE_TAG_PARAMETERS)) != NULL)
class->parameters = glade_parameter_list_new_from_node (class->parameters, child);
glade_parameter_get_boolean (class->parameters, GLADE_TAG_OPTIONAL, &class->optional);
/* Whether or not the property is translatable. This is only used for
* string properties.
*/
class->translatable = glade_xml_get_property_boolean (node, GLADE_TAG_TRANSLATABLE, TRUE);
class->translatable = glade_xml_get_property_boolean (node, GLADE_TAG_TRANSLATABLE,
class->translatable);
/* common, optional, etc */
class->common = glade_xml_get_property_boolean (node, GLADE_TAG_COMMON, class->common);
@ -1166,6 +1293,12 @@ glade_property_class_update_from_node (GladeXmlNode *node,
class->ignore = glade_xml_get_property_boolean (node, GLADE_TAG_IGNORE, class->ignore);
class->resource = glade_xml_get_property_boolean (node, GLADE_TAG_RESOURCE, class->resource);
/* Atk relations are 'atk properties' */
if ((class->atk_relation =
glade_xml_get_property_boolean (node, GLADE_TAG_ATK_RELATION,
class->atk_relation)) == TRUE)
class->atk_property = TRUE;
/* Special case pixbuf here.
*/
if (class->pspec->value_type == GDK_TYPE_PIXBUF)
@ -1173,82 +1306,14 @@ glade_property_class_update_from_node (GladeXmlNode *node,
if (class->optional)
class->optional_default =
glade_xml_get_property_boolean (node, GLADE_TAG_OPTIONAL_DEFAULT, FALSE);
glade_xml_get_property_boolean (node, GLADE_TAG_OPTIONAL_DEFAULT,
class->optional_default);
/* If this property can't be set with g_object_set, get the work around
* function
/* Get any delagate functions for accessing this property
*/
/* I use here a g_warning to signal these errors instead of a dialog
* box, as if there is one of this kind of errors, there will probably
* a lot of them, and we don't want to inflict the user the pain of
* plenty of dialog boxes. Ideally, we should collect these errors,
* and show all of them at the end of the load process.
*/
child = glade_xml_search_child (node, GLADE_TAG_SET_FUNCTION);
if (child)
{
gchar *symbol_name = glade_xml_get_content (child);
if (!module)
g_warning (_("The property [%s] of the widget's class [%s] "
"needs a special \"set\" function, but there is "
"no library associated to this widget's class."),
class->name, g_type_name (object_type));
if (!g_module_symbol (module, symbol_name, (gpointer *)
&class->set_function))
g_warning (_("Unable to get the \"set\" function [%s] of the "
"property [%s] of the widget's class [%s] from "
"the module [%s]: %s"),
symbol_name, class->name, g_type_name (object_type),
g_module_name (module), g_module_error ());
g_free (symbol_name);
}
/* If this property can't be get with g_object_get, get the work around
* function
*/
child = glade_xml_search_child (node, GLADE_TAG_GET_FUNCTION);
if (child)
{
gchar *symbol_name = glade_xml_get_content (child);
if (!module)
g_warning (_("The property [%s] of the widget's class [%s] needs a "
"special \"get\" function, but there is no library "
"associated to this widget's class."),
class->name, g_type_name (object_type));
if (!g_module_symbol(module, symbol_name,
(gpointer *) &class->get_function))
g_warning (_("Unable to get the \"get\" function [%s] of the "
"property [%s] of the widget's class [%s] from the "
"module [%s]: %s"),
symbol_name, class->name, g_type_name (object_type),
g_module_name (module), g_module_error ());
g_free (symbol_name);
}
child = glade_xml_search_child (node, GLADE_TAG_VERIFY_FUNCTION);
if (child)
{
gchar *symbol_name = glade_xml_get_content (child);
if (!module)
g_warning (_("The property [%s] of the widget's class [%s] needs a "
"special \"get\" function, but there is no library "
"associated to this widget's class."),
class->name, g_type_name (object_type));
if (!g_module_symbol(module, symbol_name,
(gpointer *) &class->verify_function))
g_warning (_("Unable to get the \"verify\" function [%s] of the "
"property [%s] of the widget's class [%s] from the "
"module [%s]: %s"),
symbol_name, class->name, g_type_name (object_type),
g_module_name (module), g_module_error ());
g_free (symbol_name);
}
glade_xml_load_sym_from_node (node, module, GLADE_TAG_SET_FUNCTION, (gpointer *)&class->set_function);
glade_xml_load_sym_from_node (node, module, GLADE_TAG_GET_FUNCTION, (gpointer *)&class->get_function);
glade_xml_load_sym_from_node (node, module, GLADE_TAG_VERIFY_FUNCTION, (gpointer *)&class->verify_function);
/* notify that we changed the property class */
class->is_modified = TRUE;

View File

@ -8,13 +8,11 @@ G_BEGIN_DECLS
* All entries in the GladeEditor are GladeProperties (except signals)
* All GladeProperties are associated with a GParamSpec.
*/
#define GLADE_PROPERTY_CLASS(gpc) ((GladePropertyClass *) gpc)
#define GLADE_IS_PROPERTY_CLASS(gpc) (gpc != NULL)
#define GLADE_PROPERTY_CLASS(gpc) ((GladePropertyClass *) gpc)
#define GLADE_IS_PROPERTY_CLASS(gpc) (gpc != NULL)
typedef struct _GladePropertyClass GladePropertyClass;
/**
* GladeVerifyPropertyFunc:
* @object: A #GObject
@ -45,6 +43,7 @@ typedef void (* GladeSetPropertyFunc) (GObject *object,
typedef void (* GladeGetPropertyFunc) (GObject *object,
GValue *value);
struct _GladePropertyClass
{
GParamSpec *pspec; /* The Parameter Specification for this property.
@ -97,6 +96,11 @@ struct _GladePropertyClass
gboolean common; /* Common properties go in the common tab */
gboolean packing; /* Packing properties go in the packing tab */
gboolean atk_property; /* atk props go in the a11y tab */
gboolean atk_relation; /* whether this is an atk relation property
* (they are saved/loaded differently)
*/
gboolean translatable; /* The property should be translatable, which
* means that it needs extra parameters in the
* UI.
@ -188,10 +192,6 @@ gboolean glade_property_class_update_from_node (GladeXmlNode
GladePropertyClass **property_class,
const gchar *domain);
LIBGLADEUI_API
gchar *glade_property_class_make_string_from_flags (GladePropertyClass *class,
guint fvals,
gboolean displayables);
LIBGLADEUI_API
gchar *glade_property_class_get_displayable_value (GladePropertyClass *class,
gint value);
LIBGLADEUI_API

View File

@ -221,9 +221,14 @@ glade_property_get_default_impl (GladeProperty *property, GValue *value)
static void
glade_property_sync_impl (GladeProperty *property)
{
if (property->enabled == FALSE ||
property->class->ignore ||
property->syncing)
/* Heh, here are the many reasons not to
* sync a property ;-)
*/
if (property->enabled == FALSE || /* optional properties that are disabled */
property->class->ignore || /* catalog says "never sync" */
property->class->atk_property || /* dont bother with atk related properties */
property->syncing) /* avoid recursion */
return;
property->syncing = TRUE;
@ -600,14 +605,7 @@ glade_property_new (GladePropertyClass *class,
property->widget = widget;
property->value = value;
if (G_IS_PARAM_SPEC_DOUBLE (class->pspec) ||
G_IS_PARAM_SPEC_FLOAT (class->pspec) ||
G_IS_PARAM_SPEC_LONG (class->pspec) ||
G_IS_PARAM_SPEC_ULONG (class->pspec) ||
G_IS_PARAM_SPEC_INT64 (class->pspec) ||
G_IS_PARAM_SPEC_UINT64 (class->pspec) ||
G_IS_PARAM_SPEC_INT (class->pspec) ||
G_IS_PARAM_SPEC_UINT (class->pspec))
if (class->optional)
property->enabled = class->optional_default;
if (property->value == NULL)

View File

@ -116,7 +116,6 @@ gboolean glade_util_copy_file (const gchar *src_path,
const gchar *dest_path);
G_END_DECLS
#endif /* __GLADE_UTILS_H__ */

View File

@ -119,54 +119,88 @@ static GList *
gwc_props_from_pspecs (GParamSpec **specs, gint n_specs)
{
GladePropertyClass *property_class;
GParamSpec *spec;
gint i;
GList *list = NULL;
for (i = 0; i < n_specs; i++)
{
spec = specs[i];
/* We only use the writable properties */
if (spec->flags & G_PARAM_WRITABLE)
{
property_class = glade_property_class_new_from_spec (spec);
if (!property_class)
continue;
/* Flag the construct only properties */
if (spec->flags & G_PARAM_CONSTRUCT_ONLY)
property_class->construct_only = TRUE;
if ((property_class =
glade_property_class_new_from_spec (specs[i])) != NULL)
list = g_list_prepend (list, property_class);
}
}
return g_list_reverse (list);
}
static gboolean
gwc_class_implements_interface (GType class_type,
GType iface_type)
{
GType *ifaces;
guint n_ifaces, i;
gboolean implemented = FALSE;
if ((ifaces = g_type_interfaces (class_type, &n_ifaces)) != NULL)
{
for (i = 0; i < n_ifaces; i++)
if (ifaces[i] == iface_type)
{
implemented = TRUE;
break;
}
g_free (ifaces);
}
return implemented;
}
static GList *
glade_widget_class_list_properties (GladeWidgetClass *class)
{
GObjectClass *object_class;
GParamSpec **specs = NULL;
guint n_specs = 0;
GList *list;
GList *list, *atk_list = NULL;
g_return_val_if_fail (GLADE_IS_WIDGET_CLASS (class), NULL);
/* Let it leek */
if ((object_class = g_type_class_ref (class->type)) == NULL)
{
g_warning ("Failed to get class for type %s\n",
g_type_name (class->type));
g_critical ("Failed to get class for type %s\n",
g_type_name (class->type));
return NULL;
}
/* list class properties */
specs = g_object_class_list_properties (object_class, &n_specs);
list = gwc_props_from_pspecs (specs, n_specs);
g_free (specs);
return list;
#if 0
/* XXX ATK compiled out for now, just for cvs sake.
*/
/* XXX FIXME: We shouldnt just do ATK_TYPE_OBJECT, we need
* to instanciate an object of the right type and use
* atk_implementor_ref_accessible()... so as to get the correct
* ATK_TYPE_OBJECT derivative (this might be overkill for the
* task at hand...)
*/
/* list atk properties if applicable */
if (gwc_class_implements_interface (class->type, ATK_TYPE_IMPLEMENTOR))
{
if ((object_class = g_type_class_ref (ATK_TYPE_OBJECT)) == NULL)
g_critical ("Failed to get class for type %s\n",
g_type_name (ATK_TYPE_OBJECT));
/* list atk properties */
specs = g_object_class_list_properties (object_class, &n_specs);
atk_list = gwc_props_from_pspecs (specs, n_specs);
g_free (specs);
}
#endif
return g_list_concat (list, atk_list);
}
static GList *
@ -196,7 +230,13 @@ glade_widget_class_list_child_properties (GladeWidgetClass *class)
list = gwc_props_from_pspecs (specs, n_specs);
g_free (specs);
/* Mark packing props */
/* We have to mark packing properties from GladeWidgetClass
* because GladePropertyClass doesnt have a valid parent GType
* to introspect it.
*
* (which could be used to call gtk_container_class_find_child_property()
* and properly introspect whether or not its a packing property).
*/
for (l = list; l; l = l->next)
{
property_class = l->data;
@ -445,22 +485,6 @@ glade_widget_class_find_child_by_type (GladeSupportedChild *child, GType type)
return child->type - type;
}
static void
glade_widget_class_load_function (GladeXmlNode *node,
GModule *module,
gchar *tagname,
void **func_location)
{
gchar *buff;
if ((buff = glade_xml_get_value_string (node, tagname)) != NULL)
{
if (!g_module_symbol (module, buff, func_location))
g_warning ("Could not find %s in %s\n",
buff, g_module_name (module));
g_free (buff);
}
}
static void
glade_widget_class_update_children_from_node (GladeXmlNode *node,
GladeWidgetClass *widget_class,
@ -518,27 +542,27 @@ glade_widget_class_update_children_from_node (GladeXmlNode *node,
if (widget_class->module)
{
glade_widget_class_load_function (child_node, widget_class->module,
GLADE_TAG_ADD_CHILD_FUNCTION,
(void **)&child->add);
glade_widget_class_load_function (child_node, widget_class->module,
GLADE_TAG_REMOVE_CHILD_FUNCTION,
(void **)&child->remove);
glade_widget_class_load_function (child_node, widget_class->module,
GLADE_TAG_GET_CHILDREN_FUNCTION,
(void **)&child->get_children);
glade_widget_class_load_function (child_node, widget_class->module,
GLADE_TAG_GET_ALL_CHILDREN_FUNCTION,
(void **)&child->get_all_children);
glade_widget_class_load_function (child_node, widget_class->module,
GLADE_TAG_CHILD_SET_PROP_FUNCTION,
(void **)&child->set_property);
glade_widget_class_load_function (child_node, widget_class->module,
GLADE_TAG_CHILD_GET_PROP_FUNCTION,
(void **)&child->get_property);
glade_widget_class_load_function (child_node, widget_class->module,
GLADE_TAG_REPLACE_CHILD_FUNCTION,
(void **)&child->replace_child);
glade_xml_load_sym_from_node (child_node, widget_class->module,
GLADE_TAG_ADD_CHILD_FUNCTION,
(gpointer *)&child->add);
glade_xml_load_sym_from_node (child_node, widget_class->module,
GLADE_TAG_REMOVE_CHILD_FUNCTION,
(gpointer *)&child->remove);
glade_xml_load_sym_from_node (child_node, widget_class->module,
GLADE_TAG_GET_CHILDREN_FUNCTION,
(gpointer *)&child->get_children);
glade_xml_load_sym_from_node (child_node, widget_class->module,
GLADE_TAG_GET_ALL_CHILDREN_FUNCTION,
(gpointer *)&child->get_all_children);
glade_xml_load_sym_from_node (child_node, widget_class->module,
GLADE_TAG_CHILD_SET_PROP_FUNCTION,
(gpointer *)&child->set_property);
glade_xml_load_sym_from_node (child_node, widget_class->module,
GLADE_TAG_CHILD_GET_PROP_FUNCTION,
(gpointer *)&child->get_property);
glade_xml_load_sym_from_node (child_node, widget_class->module,
GLADE_TAG_REPLACE_CHILD_FUNCTION,
(gpointer *)&child->replace_child);
}
/* if we found a <Properties> tag on the xml file, we add the
@ -568,22 +592,22 @@ glade_widget_class_extend_with_node (GladeWidgetClass *widget_class,
if (widget_class->module)
{
glade_widget_class_load_function (node, widget_class->module,
GLADE_TAG_POST_CREATE_FUNCTION,
(void **)&widget_class->post_create_function);
glade_xml_load_sym_from_node (node, widget_class->module,
GLADE_TAG_POST_CREATE_FUNCTION,
(void **)&widget_class->post_create_function);
glade_widget_class_load_function (node, widget_class->module,
GLADE_TAG_GET_INTERNAL_CHILD_FUNCTION,
(void **)&widget_class->get_internal_child);
glade_xml_load_sym_from_node (node, widget_class->module,
GLADE_TAG_GET_INTERNAL_CHILD_FUNCTION,
(void **)&widget_class->get_internal_child);
glade_widget_class_load_function (node, widget_class->module,
GLADE_TAG_GET_INTERNAL_CHILDREN_FUNCTION,
(void **)&widget_class->get_internal_children);
glade_xml_load_sym_from_node (node, widget_class->module,
GLADE_TAG_GET_INTERNAL_CHILDREN_FUNCTION,
(void **)&widget_class->get_internal_children);
glade_widget_class_load_function (node, widget_class->module,
GLADE_TAG_LAUNCH_EDITOR_FUNCTION,
(void **)
&widget_class->launch_editor);
glade_xml_load_sym_from_node (node, widget_class->module,
GLADE_TAG_LAUNCH_EDITOR_FUNCTION,
(void **)
&widget_class->launch_editor);
}
/* if we found a <properties> tag on the xml file, we add the properties

View File

@ -188,7 +188,8 @@ struct _GladeWidgetClass
GList *children; /* List of GladeSupportedChild objects */
GList *child_packings; /* Private */
GList *child_packings; /* Default packing property values */
GModule *module; /* Module with the (optional) special functions
* needed for placeholder_replace, post_create_function

View File

@ -711,15 +711,25 @@ glade_widget_internal_new (const gchar *name,
/**
* glade_widget_new:
* @parent: a #GladeWidget
* @klass: a #GladeWidgetClass
* @project: a #GladeProject
* @query: whether or not to query the user for properties that demanded it.
*
* TODO: write me
* Creates a #GladeWidget wrapper and the appropriate type of #GObject inside
* and add it to @project and @parent if specified.
*
* Returns:
* The resulting object will have all default properties applied to it
* including the overrides specified in the catalog, unless the catalog
* has specified 'ignore' for that property.
*
* Returns: The newly created #GladeWidget
*/
GladeWidget *
glade_widget_new (GladeWidget *parent, GladeWidgetClass *klass, GladeProject *project)
glade_widget_new (GladeWidget *parent,
GladeWidgetClass *klass,
GladeProject *project,
gboolean query)
{
GladeWidget *widget;
gchar *widget_name =
@ -729,7 +739,7 @@ glade_widget_new (GladeWidget *parent, GladeWidgetClass *klass, GladeProject *pr
if ((widget = glade_widget_internal_new
(widget_name, parent, klass, project, NULL, GLADE_CREATE_USER)) != NULL)
{
if (widget->query_user)
if (query && widget->query_user)
{
GladeEditor *editor = glade_default_app_get_editor ();

View File

@ -110,7 +110,8 @@ GType glade_widget_get_type (void);
LIBGLADEUI_API
GladeWidget * glade_widget_new (GladeWidget *parent,
GladeWidgetClass *klass,
GladeProject *project);
GladeProject *project,
gboolean query);
LIBGLADEUI_API
GladeWidget * glade_widget_new_for_internal_child (GladeWidget *parent,
GObject *internal_object,

View File

@ -124,20 +124,12 @@ static gchar *
glade_xml_get_value (xmlNodePtr node, const gchar *name)
{
xmlNodePtr child;
gchar *translatable = g_strdup_printf ("_%s", name);
gchar *ret = NULL;
/* For some reason, the leading underscores on translatable
* xml content are not stripped from widget catalogs
* (but the leading underscores on properties are),
* so we must check for the leading underscore varients.
*/
for (child = node->children; child; child = child->next)
if (!xmlStrcmp (child->name, BAD_CAST(name)) ||
!xmlStrcmp (child->name, BAD_CAST(translatable)))
if (!xmlStrcmp (child->name, BAD_CAST(name)))
ret = claim_string (xmlNodeGetContent(child));
g_free (translatable);
return ret;
}
@ -243,7 +235,6 @@ glade_xml_get_value_int_required (GladeXmlNode *node, const gchar *name, gint *
return ret;
}
/*
* Get a String value for a node either carried as an attibute or as
* the content of a child.
@ -735,3 +726,41 @@ alloc_propname(GladeInterface *interface, const gchar *string)
return alloc_string(interface, norm_str->str);
}
void
glade_xml_load_sym_from_node (GladeXmlNode *node_in,
GModule *module,
gchar *tagname,
gpointer *sym_location)
{
xmlNodePtr node = (xmlNodePtr) node_in;
gchar *buff;
if ((buff = glade_xml_get_value_string (node_in, tagname)) != NULL)
{
if (!module)
{
g_warning ("Catalog specified symbol '%s' for tag '%s', "
"no module available to load it from !",
buff, tagname);
g_free (buff);
return;
}
/* I use here a g_warning to signal these errors instead of a dialog
* box, as if there is one of this kind of errors, there will probably
* a lot of them, and we don't want to inflict the user the pain of
* plenty of dialog boxes. Ideally, we should collect these errors,
* and show all of them at the end of the load process.
*
* I dont know who wrote the above in glade-property-class.c, but
* its a good point... makeing a bugzilla entry.
* -Tristan
*/
if (!g_module_symbol (module, buff, sym_location))
g_warning ("Could not find %s in %s\n",
buff, g_module_name (module));
g_free (buff);
}
}

View File

@ -73,6 +73,10 @@ GladeXmlDoc * glade_xml_context_get_doc (GladeXmlContext *context);
gchar * alloc_string (GladeInterface *interface, const gchar *string);
gchar * alloc_propname (GladeInterface *interface, const gchar *string);
void glade_xml_load_sym_from_node (GladeXmlNode *node_in,
GModule *module,
gchar *tagname,
gpointer *sym_location);
G_END_DECLS

View File

@ -132,6 +132,7 @@ typedef struct _GladeProject GladeProject;
#define GLADE_TAG_IGNORE "ignore"
#define GLADE_TAG_VISIBLE_LINES "visible-lines"
#define GLADE_TAG_RESOURCE "resource"
#define GLADE_TAG_ATK_RELATION "atk-relation"
#define GLADE_NUMERICAL_STEP_INCREMENT 1
#define GLADE_FLOATING_STEP_INCREMENT 0.01F