Commit d1f3913c authored by Tristan Van Berkom's avatar Tristan Van Berkom

Fixed invisible labels in the menu editor.


	* gladeui/glade-editor-property.c: Fixed invisible labels in
	the menu editor.

	* gladeui/glade-widget.c, gladeui/glade-widget.h, gladeui/glade-xml-utils.c,
	gladeui/glade-utils.c, gladeui/glade-xml-utils.h, gladeui/glade-utils.h,
	gladeui/glade-property.c, gladeui/glade-property-class.c,
	gladeui/glade-property-class.h, gladeui/glade-project.c, gladeui/glade-project.h:
	implemented "factory-stock-id" in the catalog, this allows you to take a resource
	image file property formerly hacked as a custom property in libglade, and glade
	will generate a hidden icon factory in builder files so that it will be loaded
	through the stock system instead, "factory-stock-id" depicts the name of the
	stock property of the property-class in question.


svn path=/trunk/; revision=1796
parent bdabf9e7
2008-04-10 Tristan Van Berkom <tvb@gnome.org>
2008-04-12 Tristan Van Berkom <tvb@gnome.org>
* gladeui/glade-editor-property.c: Fixed invisible labels in
the menu editor.
* gladeui/glade-widget.c, gladeui/glade-widget.h, gladeui/glade-xml-utils.c,
gladeui/glade-utils.c, gladeui/glade-xml-utils.h, gladeui/glade-utils.h,
gladeui/glade-property.c, gladeui/glade-property-class.c,
gladeui/glade-property-class.h, gladeui/glade-project.c, gladeui/glade-project.h:
implemented "factory-stock-id" in the catalog, this allows you to take a resource
image file property formerly hacked as a custom property in libglade, and glade
will generate a hidden icon factory in builder files so that it will be loaded
through the stock system instead, "factory-stock-id" depicts the name of the
stock property of the property-class in question.
2008-04-11 Tristan Van Berkom <tvb@gnome.org>
* gladeui/glade-property.c:
- Fixed bold modified state for disabled properties.
......
......@@ -150,9 +150,6 @@ glade_editor_property_value_changed_cb (GladeProperty *property,
glade_editor_property_load (eprop, eprop->property);
}
static void
glade_editor_property_fix_label (GladeEditorProperty *eprop)
{
......@@ -333,6 +330,7 @@ glade_editor_property_constructor (GType type,
gtk_box_pack_start (GTK_BOX (hbox), eprop->warning, FALSE, TRUE, 0);
gtk_box_pack_start (GTK_BOX (hbox), eprop->label, TRUE, TRUE, 0);
gtk_container_add (GTK_CONTAINER (eprop->item_label), hbox);
gtk_widget_show_all (eprop->item_label);
glade_editor_property_fix_label (eprop);
......
......@@ -126,8 +126,15 @@ struct _GladeProjectPrivate
GHashTable *target_versions_major; /* target versions by catalog */
GHashTable *target_versions_minor; /* target versions by catalog */
GList *loaded_factory_files;
};
typedef struct {
gchar *stock;
gchar *filename;
} StockFilePair;
static guint glade_project_signals[LAST_SIGNAL] = {0};
......@@ -137,6 +144,11 @@ static GladeIDAllocator *unsaved_number_allocator = NULL;
G_DEFINE_TYPE (GladeProject, glade_project, G_TYPE_OBJECT)
#define GLADE_GENERATED_ICON_FACTORY_NAME "glade-generated-icon-factory"
#define GLADE_ICON_FACTORY_CLASS_NAME "GtkIconFactory"
/*******************************************************************
GObjectClass
*******************************************************************/
......@@ -1131,6 +1143,207 @@ glade_project_read_comment (GladeProject *project, GladeXmlDoc *doc)
*/
}
static GList *
glade_project_get_factory_stock_id_props (GladeProject *project)
{
GladeWidget *widget;
GladeProperty *property;
GList *list, *l;
GList *properties = NULL;
for (list = project->priv->objects; list; list = list->next)
{
widget = glade_widget_get_from_gobject (list->data);
for (l = widget->properties; l; l = l->next)
{
property = l->data;
if (property->klass->factory_stock_id &&
property->enabled &&
!glade_property_default (property))
properties = g_list_prepend (properties, property);
}
for (l = widget->packing_properties; l; l = l->next)
{
property = l->data;
if (property->klass->factory_stock_id &&
property->enabled &&
!glade_property_default (property))
properties = g_list_prepend (properties, property);
}
}
return properties;
}
static void
glade_project_generate_nodes (GladeProject *project,
GladeXmlContext *context,
GladeXmlNode *node)
{
GladeProperty *property;
GladeXmlNode *widget_node;
GladeXmlNode *source_node;
GladeXmlNode *sources_node;
GList *properties, *list;
gchar *icon_name, *filename;
if (project->priv->format == GLADE_PROJECT_FORMAT_GTKBUILDER &&
(properties = glade_project_get_factory_stock_id_props (project)))
{
widget_node = glade_xml_node_new
(context, GLADE_XML_TAG_WIDGET (project->priv->format));
glade_xml_node_append_child (node, widget_node);
/* Set class and id */
glade_xml_node_set_property_string (widget_node,
GLADE_XML_TAG_CLASS,
GLADE_ICON_FACTORY_CLASS_NAME);
glade_xml_node_set_property_string (widget_node,
GLADE_XML_TAG_ID,
GLADE_GENERATED_ICON_FACTORY_NAME);
sources_node = glade_xml_node_new (context, GLADE_XML_TAG_SOURCES);
glade_xml_node_append_child (widget_node, sources_node);
for (list = properties; list; list = list->next)
{
property = list->data;
source_node = glade_xml_node_new (context, GLADE_XML_TAG_SOURCE);
glade_xml_node_append_child (sources_node, source_node);
if ((filename = glade_widget_adaptor_string_from_value
(GLADE_WIDGET_ADAPTOR (property->klass->handle),
property->klass, property->value)) != NULL)
{
icon_name = glade_util_filename_to_icon_name (filename);
/* Set stock-id and filename */
glade_xml_node_set_property_string
(source_node,
GLADE_XML_TAG_STOCK_ID,
icon_name);
glade_xml_node_set_property_string (source_node,
GLADE_XML_TAG_FILENAME,
filename);
g_free (icon_name);
g_free (filename);
}
}
g_list_free (properties);
}
}
gboolean
glade_project_is_loaded_factory_file (GladeProject *project,
const gchar *stock_id)
{
GList *list;
StockFilePair *pair;
for (list = project->priv->loaded_factory_files;
list; list = list->next)
{
pair = list->data;
if (!strcmp (stock_id, pair->stock))
return TRUE;
}
return FALSE;
}
static void
glade_project_free_loaded_factory_files (GladeProject *project)
{
GList *list;
StockFilePair *pair;
for (list = project->priv->loaded_factory_files;
list; list = list->next)
{
pair = list->data;
g_free (pair->stock);
g_free (pair->filename);
g_free (pair);
}
g_list_free (project->priv->loaded_factory_files);
project->priv->loaded_factory_files = NULL;
}
static void
glade_project_read_factory_files (GladeProject *project,
GladeXmlNode *node)
{
GladeXmlNode *source;
StockFilePair *pair;
if ((source =
glade_xml_search_child_required (node, GLADE_XML_TAG_SOURCES)))
{
for (source = glade_xml_node_get_children (source);
source; source = glade_xml_node_next (source))
{
if (!glade_xml_node_verify (source, GLADE_XML_TAG_SOURCE))
continue;
pair = g_new (StockFilePair, 1);
pair->stock = glade_xml_get_property_string_required
(source, GLADE_XML_TAG_STOCK_ID, NULL);
pair->filename = glade_xml_get_property_string_required
(source, GLADE_XML_TAG_FILENAME, NULL);
if (!pair->stock || !pair->filename)
{
g_free (pair->stock);
g_free (pair->filename);
g_free (pair);
continue;
}
project->priv->loaded_factory_files =
g_list_prepend (project->priv->loaded_factory_files, pair);
}
}
}
static gboolean
glade_project_is_generated_node (GladeProject *project,
GladeXmlNode *node)
{
gboolean generated = FALSE;
gchar *klass, *id;
if (!glade_xml_node_verify
(node, GLADE_XML_TAG_WIDGET (project->priv->format)))
return FALSE;
if ((klass =
glade_xml_get_property_string_required
(node, GLADE_XML_TAG_CLASS, NULL)) != NULL)
{
if ((id =
glade_xml_get_property_string_required
(node, GLADE_XML_TAG_ID, NULL)) != NULL)
{
if (!strcmp (klass, GLADE_ICON_FACTORY_CLASS_NAME) &&
!strcmp (id, GLADE_GENERATED_ICON_FACTORY_NAME))
{
/* Read in the generated stock names and files */
glade_project_read_factory_files (project, node);
generated = TRUE;
}
g_free (id);
}
g_free (klass);
}
return generated;
}
gboolean
glade_project_load_from_file (GladeProject *project, const gchar *path)
......@@ -1188,6 +1401,10 @@ glade_project_load_from_file (GladeProject *project, const gchar *path)
(node, GLADE_XML_TAG_WIDGET (project->priv->format)))
continue;
/* Skip toplevel glade generated nodes */
if (glade_project_is_generated_node (project, node))
continue;
if ((widget = glade_widget_read (project, NULL, node, NULL)) != NULL)
glade_project_add_object (project, NULL, widget->object);
}
......@@ -1208,6 +1425,9 @@ glade_project_load_from_file (GladeProject *project, const gchar *path)
/* Emit "parse-finished" signal */
g_signal_emit (project, glade_project_signals [PARSE_FINISHED], 0);
/* Free up some load time metadata */
glade_project_free_loaded_factory_files (project);
/* Now we have to loop over all the object properties
* and fix'em all ('cause they probably weren't found)
......@@ -2257,6 +2477,9 @@ glade_project_write (GladeProject *project)
g_list_free (required);
}
/* Any automatically generated stuff goes here */
glade_project_generate_nodes (project, context, root);
for (list = project->priv->objects; list; list = list->next)
{
GladeWidget *widget;
......
......@@ -186,6 +186,9 @@ gchar *glade_project_verify_widget_adaptor (GladeProject *project,
GladeWidgetAdaptor *adaptor,
GladeSupportMask *mask);
gboolean glade_project_is_loaded_factory_file (GladeProject *project,
const gchar *stock_id);
G_END_DECLS
#endif /* __GLADE_PROJECT_H__ */
......@@ -122,6 +122,7 @@ glade_property_class_clone (GladePropertyClass *property_class)
clone->id = g_strdup (clone->id);
clone->name = g_strdup (clone->name);
clone->tooltip = g_strdup (clone->tooltip);
clone->factory_stock_id = g_strdup (clone->factory_stock_id);
if (G_IS_VALUE (property_class->def))
{
......@@ -1489,6 +1490,26 @@ glade_property_class_update_from_node (GladeXmlNode *node,
klass->transfer_on_paste = glade_xml_get_property_boolean (node, GLADE_TAG_TRANSFER_ON_PASTE, klass->transfer_on_paste);
klass->save_always = glade_xml_get_property_boolean (node, GLADE_TAG_SAVE_ALWAYS, klass->save_always);
/* Special case pixbuf here.
*/
if (klass->pspec->value_type == GDK_TYPE_PIXBUF)
klass->resource = TRUE;
if ((buf = glade_xml_get_property_string
(node, GLADE_TAG_FACTORY_STOCK_ID)) != NULL)
{
if (!klass->resource) /* Assert the early in the game */
g_error ("%s only supported on properties that are marked as %s",
GLADE_TAG_FACTORY_STOCK_ID,
GLADE_TAG_RESOURCE);
if (klass->factory_stock_id)
g_free (klass->factory_stock_id);
klass->factory_stock_id = buf;
}
/* If this property's value is an enumeration or flag then we try to get the displayable values */
if ((G_IS_PARAM_SPEC_ENUM(klass->pspec) || G_IS_PARAM_SPEC_FLAGS(klass->pspec)) &&
(child = glade_xml_search_child (node, GLADE_TAG_DISPLAYABLE_VALUES)))
......@@ -1499,11 +1520,6 @@ glade_property_class_update_from_node (GladeXmlNode *node,
* go in the atk tab, ideally this shouldnt be needed.
*/
klass->atk = glade_xml_get_property_boolean (node, GLADE_TAG_ATK_PROPERTY, klass->atk);
/* Special case pixbuf here.
*/
if (klass->pspec->value_type == GDK_TYPE_PIXBUF)
klass->resource = TRUE;
if (klass->optional)
klass->optional_default =
......
......@@ -151,6 +151,15 @@ struct _GladePropertyClass
* the editor.
*/
gchar *factory_stock_id; /* Used for legacy fake libglade properties
* that reffer to pixbufs, glade creates
* an internal icon factory so that builder
* can load them as stock icons. The string
* if set reffers to the property name that
* will be used to lookup the theme by the
* implementing widget
*/
};
......
......@@ -969,23 +969,28 @@ glade_property_read (GladeProperty *property,
GladeProject *project,
GladeXmlNode *node)
{
GladeProjectFormat fmt;
GladeXmlNode *prop;
GValue *gvalue = NULL;
gchar *id, *name, *value;
const gchar *search_name;
g_return_if_fail (GLADE_IS_PROPERTY (property));
g_return_if_fail (GLADE_IS_PROJECT (project));
g_return_if_fail (node != NULL);
fmt = glade_project_get_format (project);
/* 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 (glade_project_get_format (project)))))
(node, GLADE_XML_TAG_WIDGET (fmt))))
return;
for (prop = glade_xml_node_get_children (node);
prop; prop = glade_xml_node_next (prop))
{
search_name = property->klass->id;
if (!glade_xml_node_verify_silent (prop, GLADE_XML_TAG_PROPERTY))
continue;
......@@ -994,21 +999,45 @@ glade_property_read (GladeProperty *property,
(prop, GLADE_XML_TAG_NAME, NULL)))
continue;
if (!(value = glade_xml_get_content (prop)))
{
/* XXX should be glade_xml_get_content_required()... */
g_free (name);
g_free (value);
continue;
}
/* Switch up the values if we are using GtkIconFactory in builder
* to load some hacked out legacy pixbufs
*/
if (fmt == GLADE_PROJECT_FORMAT_GTKBUILDER)
{
gboolean is_loaded_value =
glade_project_is_loaded_factory_file
(property->widget->project, value);
if (property->klass->factory_stock_id && is_loaded_value)
search_name = property->klass->factory_stock_id;
/* If this property was loaded via another property, skip it... */
else if (glade_widget_has_factory_stock_id
(property->widget, property->klass->id) && is_loaded_value)
{
/* really ?... */
g_free (value);
g_free (name);
break;
}
}
/* Make sure we are working with dashes and
* not underscores ...
*/
id = glade_util_read_prop_name (name);
g_free (name);
if (!strcmp (id, property->klass->id))
if (!strcmp (id, search_name))
{
if (!(value = glade_xml_get_content (prop)))
{
/* XXX should be glade_xml_get_content_required()... */
g_free (id);
break;
}
if (property && glade_property_class_is_object (property->klass))
{
/* we must synchronize this directly after loading this project
......@@ -1021,6 +1050,15 @@ glade_property_read (GladeProperty *property,
}
else
{
if (fmt == GLADE_PROJECT_FORMAT_GTKBUILDER &&
search_name == property->klass->factory_stock_id)
{
gchar *filename =
glade_util_icon_name_to_filename (value);
g_free (value);
value = filename;
}
gvalue = glade_property_class_make_gvalue_from_string
(property->klass, value, project);
......@@ -1083,6 +1121,7 @@ glade_property_write (GladeProperty *property,
GladeXmlContext *context,
GladeXmlNode *node)
{
GladeProjectFormat fmt;
GladeXmlNode *prop_node;
GladeProject *project;
gchar *name, *value, *tmp;
......@@ -1092,10 +1131,11 @@ glade_property_write (GladeProperty *property,
project = property->widget->project;
fmt = glade_project_get_format(project);
/* 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 (glade_project_get_format(project)))))
glade_xml_node_verify_silent (node, GLADE_XML_TAG_WIDGET (fmt))))
return;
if (!property->klass->save || !property->enabled)
......@@ -1131,6 +1171,25 @@ glade_property_write (GladeProperty *property,
g_free (tmp);
}
/* Switch up the values if we are using GtkIconFactory in builder
* to save some hacked out pixbufs
*/
if (fmt == GLADE_PROJECT_FORMAT_GTKBUILDER &&
property->klass->factory_stock_id)
{
gchar *icon_name;
/* Create a string representation for the icon factory */
icon_name = glade_util_filename_to_icon_name (value);
g_free (value);
value = icon_name;
/* Use the alternate property name */
g_free (name);
name = g_strdup (property->klass->factory_stock_id);
glade_util_replace (name, '-', '_');
}
/* Now dump the node values... */
prop_node = glade_xml_node_new (context, GLADE_XML_TAG_PROPERTY);
glade_xml_node_append_child (node, prop_node);
......
......@@ -1906,3 +1906,34 @@ glade_util_get_file_mtime (const gchar *filename, GError **error)
}
}
gchar *
glade_util_filename_to_icon_name (const gchar *value)
{
gchar *icon_name, *p;
g_return_val_if_fail (value && value[0], NULL);
icon_name = g_strdup_printf ("glade-generated-%s", value);
if ((p = strrchr (icon_name, '.')) != NULL)
*p = '-';
return icon_name;
}
gchar *
glade_util_icon_name_to_filename (const gchar *value)
{
/* sscanf makes us allocate a buffer */
gchar filename[FILENAME_MAX], *p;
g_return_val_if_fail (value && value[0], NULL);
sscanf (value, "glade-generated-%s", filename);
/* XXX: Filenames without an extention will evidently
* break here
*/
if ((p = strrchr (filename, '-')) != NULL)
*p = '.';
return g_strdup (filename);
}
......@@ -130,6 +130,12 @@ time_t glade_util_get_file_mtime (const gchar *filename, GErro
gboolean glade_util_version_lesser_than (gdouble a, gdouble b);
gchar *glade_util_filename_to_icon_name (const gchar *value);
gchar *glade_util_icon_name_to_filename (const gchar *value);
G_END_DECLS
#endif /* __GLADE_UTILS_H__ */
......@@ -4112,3 +4112,30 @@ glade_widget_set_support_warning (GladeWidget *widget,
g_object_notify (G_OBJECT (widget), "support-warning");
}
gboolean
glade_widget_has_factory_stock_id (GladeWidget *widget,
const gchar *property_name)
{
GList *l;
GladeProperty *property;
g_return_val_if_fail (GLADE_IS_WIDGET (widget), FALSE);
g_return_val_if_fail (property_name, FALSE);
for (l = widget->properties; l; l = l->next)
{
property = l->data;
if (property->klass->factory_stock_id &&
!strcmp (property->klass->factory_stock_id, property_name))
return TRUE;
}
for (l = widget->packing_properties; l; l = l->next)
{
property = l->data;
if (property->klass->factory_stock_id &&
!strcmp (property->klass->factory_stock_id, property_name))
return TRUE;
}
return FALSE;
}
......@@ -402,6 +402,9 @@ void glade_widget_pop_superuser (void);
void glade_widget_set_support_warning (GladeWidget *widget,
const gchar *warning);
gboolean glade_widget_has_factory_stock_id (GladeWidget *widget,
const gchar *property_name);
G_END_DECLS
#endif /* __GLADE_WIDGET_H__ */
......@@ -498,20 +498,20 @@ glade_xml_get_property_version (GladeXmlNode *node_in,
if (!value)
return FALSE;
split = g_strsplit (value, ".", 2);
if (!split[0] || !split[1])
if ((split = g_strsplit (value, ".", 2)))
{
g_warning ("Malformed version property \"%s\"\n"
"Under the \"%s\" tag (%s)", name, node->name, value);
return FALSE;
}
if (!split[0] || !split[1])
{
g_warning ("Malformed version property \"%s\"\n"
"Under the \"%s\" tag (%s)", name, node->name, value);
return FALSE;
}
*major = g_ascii_strtoll (split[0], NULL, 10);
*minor = g_ascii_strtoll (split[1], NULL, 10);
g_strfreev (split);
*major = g_ascii_strtoll (split[0], NULL, 10);
*minor = g_ascii_strtoll (split[1], NULL, 10);
g_strfreev (split);
}
return TRUE;
}
......
......@@ -65,13 +65,17 @@ typedef struct _GladeXmlDoc GladeXmlDoc;
#define GLADE_XML_TAG_I18N_TRUE "yes"
#define GLADE_XML_TAG_SIGNAL_TRUE "yes"
#define GLADE_XML_TAG_TYPE "type"
#define GLADE_XML_TAG_SOURCES "sources"
#define GLADE_XML_TAG_SOURCE "source"
#define GLADE_XML_TAG_FILENAME "filename"
#define GLADE_XML_TAG_STOCK_ID "stock-id"
#define GLADE_TAG_VERSION "version"
#define GLADE_TAG_TARGETABLE "targetable"
#define GLADE_TAG_VERSION_SINCE "since"
#define GLADE_TAG_DEPRECATED "deprecated"
#define GLADE_TAG_BUILDER_UNSUPPORTED "builder-unsupported"
#define GLADE_TAG_FACTORY_STOCK_ID "factory-stock-id"
#define GLADE_TAG_GLADE_CATALOG "glade-catalog"
#define GLADE_TAG_GLADE_WIDGET_CLASSES "glade-widget-classes"
......
......@@ -535,7 +535,7 @@ embedded in another object</_tooltip>
<spec>glade_standard_stock_image_spec</spec>
</property>
<property id="label" translatable="True"/>
<property id="icon" _name="File Name">
<property id="icon" _name="File Name" factory-stock-id="stock-id">
<spec>glade_standard_pixbuf_spec</spec>
</property>
</properties>
......
......@@ -2989,7 +2989,6 @@ glade_window_init (GladeWindow *window)
GtkWidget *menubar;
GtkWidget *editor_item;
GtkWidget *palette;
GtkWidget *editor;
GtkWidget *dockitem;
GtkWidget *widget;
GtkWidget *sep;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment