diff options
author | Tristan Van Berkom <tvb@src.gnome.org> | 2005-01-12 15:16:57 +0000 |
---|---|---|
committer | Tristan Van Berkom <tvb@src.gnome.org> | 2005-01-12 15:16:57 +0000 |
commit | f1ab244e87c30353b6ea5e5c61218eee402efbd7 (patch) | |
tree | 007cd6f91941d66663f0af08c8de4fe561011788 | |
parent | 9a8db8e33a901e906355ae0dc2924f3f667dab34 (diff) | |
download | glade-f1ab244e87c30353b6ea5e5c61218eee402efbd7.tar.gz |
Integrating imendio work.
-rw-r--r-- | ChangeLog | 164 | ||||
-rw-r--r-- | src/glade-catalog.c | 406 | ||||
-rw-r--r-- | src/glade-catalog.h | 45 | ||||
-rw-r--r-- | src/glade-editor.c | 219 | ||||
-rw-r--r-- | src/glade-palette.c | 42 | ||||
-rw-r--r-- | src/glade-palette.h | 2 | ||||
-rw-r--r-- | src/glade-parameter.h | 2 | ||||
-rw-r--r-- | src/glade-project-view.c | 7 | ||||
-rw-r--r-- | src/glade-property-class.c | 24 | ||||
-rw-r--r-- | src/glade-property-class.h | 5 | ||||
-rw-r--r-- | src/glade-property.c | 62 | ||||
-rw-r--r-- | src/glade-property.h | 18 | ||||
-rw-r--r-- | src/glade-types.h | 1 | ||||
-rw-r--r-- | src/glade-widget-class.c | 190 | ||||
-rw-r--r-- | src/glade-widget-class.h | 8 | ||||
-rw-r--r-- | src/glade-widget.c | 50 | ||||
-rw-r--r-- | src/glade.h | 85 | ||||
-rw-r--r-- | src/main.c | 5 | ||||
-rw-r--r-- | widgets/Makefile.am | 37 | ||||
-rw-r--r-- | widgets/adding-widgets.txt | 219 | ||||
-rw-r--r-- | widgets/glade-catalog.dtd | 90 | ||||
-rw-r--r-- | widgets/gtk+.xml.in | 520 |
22 files changed, 1807 insertions, 394 deletions
@@ -1,3 +1,167 @@ +2005-01-12 Richard Hult <richard@imendio.com> + + * widgets/gtk+.xml: Change the min value for GtkBox size to 1 from + 2. Fixes #163813. + +2005-01-12 Mikael Hallendal <micke@imendio.com> + + * src/glade-property-class.c: + (glade_property_class_new_from_spec): + - Added parameter check on spec. + (glade_property_class_update_from_node): + - Handle properties not found by introspection and that don't + specify a spec-function in the catalog file as disabled properties. + Fixes a crash when loading the catalog file that has GTK+ 2.6 + properties overridden in GTK+ 2.4. + +2005-01-12 Richard Hult <richard@imendio.com> + + * widgets/adding-widgets.txt: Add first cut at documentation for + adding widgets. + + * widgets/glade-catalog.dtd: Add translatable property. + + * widgets/gtk+.xml: Change name from tooltip to Tooltip. + +2005-01-12 Richard Hult <richard@imendio.com> + + * src/glade-parameter.h: + * widgets/gtk+.xml: Fix typos in the XML. + +2005-01-11 Richard Hult <richard@imendio.com> + + * src/glade-editor.c: (glade_editor_create_input_text), + (glade_editor_append_item_real), + (glade_editor_property_load_text), + (glade_editor_property_load): Merge the translatable and + non-translatable input widgets. + + * src/glade-property.c: (glade_property_write), + (glade_property_i18n_set_comment): Remove debug spew. + + * widgets/gtk+.xml: Mark the appropriate properties + non-translatable. + +2005-01-11 Mikael Hallendal <micke@imendio.com> + + * src/glade-catalog.c: (catalog_load), (catalog_load_group): + - Hide some debug printouts + * src/glade.h: + * widgets/glade-catalog.dtd: + * widgets/gtk+.xml: + - child-property-applies to child-property-applies-function + All other functions are named like that. + +2005-01-07 Richard Hult <richard@imendio.com> + + * src/glade-editor.c: (glade_editor_property_show_i18n_dialog), + (glade_editor_create_input_text), + (glade_editor_create_input_translatable_text), + (glade_editor_append_item_real), + (glade_editor_property_load_text), + (glade_editor_property_load_translatable_text), + (glade_editor_property_load): Add i18n string handling. + + * src/glade-property.h: + * src/glade-property.c: (glade_property_new), (glade_property_dup), + (glade_property_free), (glade_property_write), + (glade_property_i18n_*): Add i18n handling. + + * src/glade-widget.c: (glade_widget_value_from_prop_info), + (glade_widget_apply_property_from_prop_info), + (glade_widget_get_property_from_widget_info), + (glade_widget_properties_from_widget_info), + (glade_widget_params_from_widget_info): Read i18n metadata + (doesn't read anything yet, we need to sort out libglade first). + +2005-01-06 Richard Hult <richard@imendio.com> + + * src/glade-property-class.h (struct _GladePropertyClass): Add + translatable value. + + * src/glade-property-class.c (glade_property_class_new): Init + translatable value. + (glade_property_class_update_from_node): Use defines for visible + and optional tags and parse translatable. + + * src/glade.h: Add tags for visible and translatable. + +2005-01-06 Mikael Hallendal <micke@imendio.com> + + * src/glade-catalog.c: (catalog_load), (catalog_load_classes), + (catalog_load_group): + * src/glade.h: + * widgets/gtk+.xml: + - More work on the catalog format. + - Replaced glade-widgets with glade-widget-classes + - Replaced glade-widget-class in groups to glade-widget-class-ref to + be more DTD friendly. Also makes more sense since it's a reference + to a widget class rather than another widget class definition. + +2005-01-06 Mikael Hallendal <micke@imendio.com> + + * src/glade-catalog.c: (catalog_load), (catalog_load_group): + * src/glade-widget-class.c: (glade_widget_class_new): + - Make sure to use the GLADE_TAG defines instead of hardcoding strings. + - Makes it easier to update the format. + * src/glade.h: + - Updated to use new format. + - Needs some more work, unsure of which tags/attributes are used in + the catalogs and which are for something else. + * widgets/Makefile.am: + * widgets/gtk+.xml: + - Update the catalog format to be more .glade like. + +2005-01-05 Mikael Hallendal <micke@imendio.com> + + * src/glade-catalog.c: (catalog_load_widgets), + (glade_catalog_load_all): + * widgets/Makefile.am: + * widgets/gtk+.catalog: Removed + * widgets/gtk+.xml: Added + - Revert and continue to call catalog files .xml + +2005-01-05 Mikael Hallendal <micke@imendio.com> + + * src/glade-catalog.[ch]: + - Removed need for the palette file, loads all .catalog files in + catalog directory. + - New catalog format where a catalog is one per library, for example + gtk+.catalog. Each catalog contains one or more widget groups. + Widget class definitions has been separated from the grouping which + means that you can have a widget in two different groups. + * src/glade-palette.c: + - Updated to add widget groups rather than catalogs to the option + menu. + (glade_palette_widget_table_create), + (glade_palette_append_widget_group): + - Renamed from glade_palette_append_catalog. + (glade_palette_new): + * src/glade-palette.h: + - Made glade_palette_append_widget_group internal. + * src/glade-types.h: + - Added GladeWidgetGroup. + * src/glade-widget-class.c: + (glade_widget_class_new): + - Reimplemented to instead take an GladeXmlNode node and load the + widget class from there. + * src/glade-widget-class.h: + - Removed glade_widget_class_new_from_node for which the implementation + was removed over a year ago. + * src/glade.h: + - Moved some GladeCatalog specific XML tags to glade-catalog.c instead. + * src/main.c: (glade_init): + - Give a warning if no catalog files where found instead of silently + exit. + * widgets/Makefile.am: + * widgets/gtk+.catalog: + - Added gtk+.catalog + +2005-01-05 Richard Hult <richard@imendio.com> + + * src/glade-project-view.c (gpv_find_preceeding_sibling): Fix + crash when there are no rows. + 2005-01-02 Tristan Van Berkom <tvb@cvs.gnome.org> * src/glade-clipboard-view.c, src/glade-palette.c, diff --git a/src/glade-catalog.c b/src/glade-catalog.c index bc779bec..ef991e87 100644 --- a/src/glade-catalog.c +++ b/src/glade-catalog.c @@ -1,6 +1,7 @@ /* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ /* * Copyright (C) 2001 Ximian, Inc. + * Copyright (C) 2004 Imendio AB * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as @@ -29,212 +30,333 @@ #include <sys/types.h> #include <sys/stat.h> -#include <glib/gdir.h> +#include <glib.h> #include "glade.h" #include "glade-catalog.h" #include "glade-widget-class.h" -#define GLADE_TAG_PALETTE "GladePalette" +#define d(x) -/** - * glade_catalog_delete: - * @catalog: - * - * Frees @catalog and its associated memory. - */ -void -glade_catalog_delete (GladeCatalog *catalog) +struct _GladeCatalog { - GList *list; + gchar *library; - if (catalog == NULL) - return; + gchar *name; + + GList *widget_groups; + GList *widget_classes; +}; + +struct _GladeWidgetGroup { + gchar *name; + gchar *title; + GList *widget_classes; +}; + +static GladeCatalog * catalog_load (const char *filename); +static gboolean catalog_load_classes (GladeCatalog *catalog, + GladeXmlNode *widgets_node); +static gboolean catalog_load_group (GladeCatalog *catalog, + GladeXmlNode *group_node); + +void widget_group_free (GladeWidgetGroup *group); - g_free (catalog->title); - for (list = catalog->widget_classes; list; list = list->next) - glade_widget_class_free (GLADE_WIDGET_CLASS (list->data)); - g_list_free (catalog->widget_classes); - g_free (catalog); -} static GladeCatalog * -glade_catalog_load (const char *base_catalog_filename) +catalog_load (const char *filename) { - GladeWidgetClass *widget_class = NULL; - GladeXmlContext *context = NULL; - GladeXmlNode *root = NULL; - GladeXmlNode *widget_node = NULL; - GladeXmlDoc *doc = NULL; - GladeCatalog *catalog = NULL; - char *name = NULL; - char *generic_name = NULL; - char *palette_name = NULL; - char *catalog_filename = NULL; - char *base_filename = NULL; - char *base_library = NULL; - GList *last_widget_class = NULL; - - catalog_filename = g_strdup_printf ("%s%c%s", glade_catalogs_dir, G_DIR_SEPARATOR, base_catalog_filename); - if (catalog_filename == NULL) - { - g_critical (_("Not enough memory.")); - goto lblError; - } + GladeCatalog *catalog; + GladeXmlContext *context; + GladeXmlDoc *doc; + GladeXmlNode *root; + GladeXmlNode *node; + d(g_print ("Loading catalog: %s\n", filename)); /* get the context & root node of the catalog file */ - context = glade_xml_context_new_from_path (catalog_filename, NULL, GLADE_TAG_CATALOG); - if (!context) + context = glade_xml_context_new_from_path (filename, + NULL, + GLADE_TAG_GLADE_CATALOG); + if (!context) { - g_warning (_("Impossible to open the catalog [%s]."), catalog_filename); - goto lblError; + g_warning ("Couldn't load catalog [%s].", filename); + return NULL; } - doc = glade_xml_context_get_doc (context); + doc = glade_xml_context_get_doc (context); root = glade_xml_doc_get_root (doc); - catalog = g_new0 (GladeCatalog, 1); + if (!glade_xml_node_verify (root, GLADE_TAG_GLADE_CATALOG)) + { + g_warning ("Catalog root node is not '%s', skipping %s", + GLADE_TAG_GLADE_CATALOG, filename); + glade_xml_context_free (context); + return NULL; + } - last_widget_class = NULL; + catalog = g_new0 (GladeCatalog, 1); - /* read the title of this catalog */ - catalog->title = glade_xml_get_property_string_required (root, "Title", catalog_filename); + catalog->name = glade_xml_get_property_string (root, GLADE_TAG_NAME); + if (!catalog->name) + { + g_warning ("Couldn't find required property 'name' in catalog root node"); + g_free (catalog); + glade_xml_context_free (context); + return NULL; + } + + catalog->library = glade_xml_get_property_string (root, + GLADE_TAG_LIBRARY); - if (!glade_xml_node_verify (root, GLADE_TAG_CATALOG)) + node = glade_xml_node_get_children (root); + for (; node; node = glade_xml_node_next (node)) { - g_warning (_("The root node of [%s] has a name different from %s."), catalog_filename, GLADE_TAG_CATALOG); - goto lblError; + const gchar *node_name; + + node_name = glade_xml_node_get_name (node); + if (strcmp (node_name, GLADE_TAG_GLADE_WIDGET_CLASSES) == 0) + { + catalog_load_classes (catalog, node); + } + else if (strcmp (node_name, GLADE_TAG_GLADE_WIDGET_GROUP) == 0) + { + catalog_load_group (catalog, node); + } + else + continue; } - /* get the library to be used by this catalog (if any) */ - base_library = glade_xml_get_property_string (root, "library"); + catalog->widget_groups = g_list_reverse (catalog->widget_groups); + + glade_xml_context_free (context); + + d(g_print ("Successfully parsed catalog: %s\n", catalog->name)); + + return catalog; +} + +static gboolean +catalog_load_classes (GladeCatalog *catalog, GladeXmlNode *widgets_node) +{ + GladeXmlNode *node; - /* build all the GladeWidgetClass'es associated with this catalog */ - widget_node = glade_xml_node_get_children (root); - for (; widget_node; widget_node = glade_xml_node_next (widget_node)) + node = glade_xml_node_get_children (widgets_node); + for (; node; node = glade_xml_node_next (node)) { - char *base_widget_class_library = NULL; + const gchar *node_name; + GladeWidgetClass *widget_class; - if (!glade_xml_node_verify (widget_node, GLADE_TAG_GLADE_WIDGET)) + node_name = glade_xml_node_get_name (node); + if (strcmp (node_name, GLADE_TAG_GLADE_WIDGET_CLASS) != 0) continue; + + widget_class = glade_widget_class_new (node, + catalog->library); - name = glade_xml_get_property_string_required (widget_node, "name", catalog_filename); - if (!name) - continue; + catalog->widget_classes = g_list_prepend (catalog->widget_classes, + widget_class); + } + + return TRUE; +} - /* get the specific library to the widget class, if any */ - base_widget_class_library = glade_xml_get_property_string (widget_node, "library"); - generic_name = glade_xml_get_property_string (widget_node, "generic_name"); - palette_name = glade_xml_get_property_string (widget_node, "palette_name"); +static gboolean +catalog_load_group (GladeCatalog *catalog, GladeXmlNode *group_node) +{ + GladeWidgetGroup *group; + GladeXmlNode *node; + + group = g_new0 (GladeWidgetGroup, 1); + + group->name = glade_xml_get_property_string (group_node, + GLADE_TAG_NAME); + if (!group->name) + { + g_warning ("Required property 'name' not found in group node"); + + widget_group_free (group); + return FALSE; + } + + group->title = glade_xml_get_property_string (group_node, + GLADE_TAG_TITLE); + if (!group->title) + { + g_warning ("Required property 'title' not found in group node"); + + widget_group_free (group); + return FALSE; + } + + d(g_print ("Loading widget group: %s\n", group->title)); + + group->widget_classes = NULL; + + node = glade_xml_node_get_children (group_node); + for (; node; node = glade_xml_node_next (node)) + { + const gchar *node_name; + GladeWidgetClass *widget_class; + gchar *name; + + node_name = glade_xml_node_get_name (node); - base_filename = glade_xml_get_property_string (widget_node, "filename"); + if (strcmp (node_name, GLADE_TAG_GLADE_WIDGET_CLASS_REF) != 0) + continue; - widget_class = glade_widget_class_new (name, generic_name, palette_name, base_filename, - base_widget_class_library ? base_widget_class_library : base_library); - if (widget_class) + name = glade_xml_get_property_string (node, GLADE_TAG_NAME); + if (!name) { - last_widget_class = g_list_append (last_widget_class, widget_class); - - if (last_widget_class->next != NULL) - last_widget_class = last_widget_class->next; - else - catalog->widget_classes = last_widget_class; + g_warning ("Couldn't find required property on %s", + GLADE_TAG_GLADE_WIDGET_CLASS); + continue; } + widget_class = glade_widget_class_get_by_name (name); + if (!widget_class) + { + g_warning ("Tried to include undefined widget class '%s' in a widget group", name); + g_free (name); + continue; + } g_free (name); - g_free (generic_name); - g_free (palette_name); - g_free (base_filename); - g_free (base_widget_class_library); + + group->widget_classes = g_list_prepend (group->widget_classes, + widget_class); } - glade_xml_context_free (context); - g_free (catalog_filename); - g_free (base_library); - return catalog; + group->widget_classes = g_list_reverse (group->widget_classes); -lblError: - glade_xml_context_free (context); - g_free (catalog_filename); - g_free (catalog); - g_free (base_library); - return NULL; + catalog->widget_groups = g_list_prepend (catalog->widget_groups, + group); + + return TRUE; } -/** - * glade_catalog_load_all: - * - * TODO: write me - * - * Returns: - */ +void +widget_group_free (GladeWidgetGroup *group) +{ + g_return_if_fail (group != NULL); + + g_free (group->name); + g_free (group->title); + + /* The actual widget classes will be free elsewhere */ + g_list_free (group->widget_classes); +} + GList * glade_catalog_load_all (void) { - gchar *filename = g_build_filename (glade_catalogs_dir, "glade-palette.xml", NULL); - GladeXmlContext *context; - GladeXmlNode *root; - GladeXmlNode *xml_catalogs; - GladeXmlDoc *doc; - GList *catalogs = NULL; + GDir *dir; + GError *error; + const gchar *filename; + GList *catalogs; GladeCatalog *catalog; - - context = glade_xml_context_new_from_path (filename, NULL, GLADE_TAG_PALETTE); - if (context == NULL) + + /* Read all files in catalog dir */ + dir = g_dir_open (glade_catalogs_dir, 0, &error); + if (!dir) { - g_critical ("Unable to open %s.\n", filename); + g_warning ("Failed to open catalog directory: %s", + error->message); return NULL; } - doc = glade_xml_context_get_doc (context); - root = glade_xml_doc_get_root (doc); - xml_catalogs = glade_xml_node_get_children (root); - while (xml_catalogs != NULL) { - char *name = glade_xml_get_property_string_required (xml_catalogs, "filename", NULL); + catalogs = NULL; + while ((filename = g_dir_read_name (dir))) + { + gchar *catalog_filename; - if (!strcmp(glade_xml_node_get_name (xml_catalogs), GLADE_TAG_CATALOG)) - { - catalog = glade_catalog_load (name); - if (catalog) - catalogs = g_list_append (catalogs, catalog); - else - g_warning ("Unable to open the catalog %s.\n", name); - } - else - g_warning ("The palette file \"glade-palette.xml\" has " - "a node with name %s instead of " GLADE_TAG_CATALOG "\n", name); + if (!g_str_has_suffix (filename, ".xml")) + continue; - xml_catalogs = glade_xml_node_next (xml_catalogs); - g_free (name); + catalog_filename = g_build_filename (glade_catalogs_dir, + filename, NULL); + catalog = catalog_load (catalog_filename); + g_free (catalog_filename); + + if (catalog) + catalogs = g_list_append (catalogs, catalog); + else + g_warning ("Unable to open the catalog file %s.\n", + filename); } - glade_xml_context_free (context); - g_free (filename); + g_dir_close (dir); + return catalogs; } -/** - * glade_catalog_get_title: - * @catalog: a #GladeCatalog - * - * Returns: a pointer to the title of @catalog - */ -const char * -glade_catalog_get_title (GladeCatalog *catalog) +const gchar * +glade_catalog_get_name (GladeCatalog *catalog) { g_return_val_if_fail (catalog != NULL, NULL); - return catalog->title; + + return catalog->name; +} + +GList * +glade_catalog_get_widget_groups (GladeCatalog *catalog) +{ + g_return_val_if_fail (catalog != NULL, NULL); + + return catalog->widget_groups; } -/** - * glade_catalog_get_widget_classes: - * @catalog: a #GladeCatalog - * - * Returns: a #GList containing the widget classes in @catalog - */ GList * glade_catalog_get_widget_classes (GladeCatalog *catalog) { g_return_val_if_fail (catalog != NULL, NULL); + return catalog->widget_classes; } + +void +glade_catalog_free (GladeCatalog *catalog) +{ + GList *list; + + if (catalog == NULL) + return; + + g_free (catalog->name); + + for (list = catalog->widget_classes; list; list = list->next) + glade_widget_class_free (GLADE_WIDGET_CLASS (list->data)); + + g_list_free (catalog->widget_classes); + + for (list = catalog->widget_groups; list; list = list->next) + widget_group_free (GLADE_WIDGET_GROUP (list->data)); + + g_list_free (catalog->widget_groups); + + + g_free (catalog); +} +const gchar * +glade_widget_group_get_name (GladeWidgetGroup *group) +{ + g_return_val_if_fail (group != NULL, NULL); + + return group->name; +} + +const gchar * +glade_widget_group_get_title (GladeWidgetGroup *group) +{ + g_return_val_if_fail (group != NULL, NULL); + + return group->title; +} + +GList * +glade_widget_group_get_widget_classes (GladeWidgetGroup *group) +{ + g_return_val_if_fail (group != NULL, NULL); + + return group->widget_classes; +} + + diff --git a/src/glade-catalog.h b/src/glade-catalog.h index 44a4cb25..491e6cbd 100644 --- a/src/glade-catalog.h +++ b/src/glade-catalog.h @@ -1,34 +1,47 @@ /* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ +/* + * Copyright (C) 2001 Ximian, Inc. + * Copyright (C) 2004 Imendio AB + * + * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. + */ + #ifndef __GLADE_CATALOG_H__ #define __GLADE_CATALOG_H__ G_BEGIN_DECLS - #define GLADE_CATALOG(c) ((GladeCatalog *) c) #define GLADE_IS_CATALOG(c) (c != NULL) +#define GLADE_WIDGET_GROUP(x) ((GladeWidgetGroup *) x) -/* The GladeCatalog is list of widgets classes. We are going to use - * a different catalog for each group of widgets like gtk-base, - * gnome, gnome-db etc. It is also used to group widgets in the - * palette. - */ -struct _GladeCatalog -{ - gchar *title; /* Title for this catalog */ - GList *widget_classes; /* list of widget classes contained on this catalog */ -}; - +GList * glade_catalog_load_all (void); -void glade_catalog_delete (GladeCatalog *catalog); +const gchar * glade_catalog_get_name (GladeCatalog *catalog); -GList *glade_catalog_load_all (void); +GList * glade_catalog_get_widget_groups (GladeCatalog *catalog); +GList * glade_catalog_get_widget_classes (GladeCatalog *catalog); -const char *glade_catalog_get_title (GladeCatalog *catalog); +void glade_catalog_free (GladeCatalog *catalog); -GList *glade_catalog_get_widget_classes (GladeCatalog *catalog); +const gchar * glade_widget_group_get_name (GladeWidgetGroup *group); +const gchar * glade_widget_group_get_title (GladeWidgetGroup *group); +GList * glade_widget_group_get_widget_classes (GladeWidgetGroup *group); +void glade_widget_group_free (GladeWidgetGroup *group); G_END_DECLS diff --git a/src/glade-editor.c b/src/glade-editor.c index a9afa3df..79dc1acc 100644 --- a/src/glade-editor.c +++ b/src/glade-editor.c @@ -44,11 +44,13 @@ #include "glade-project.h" #include "glade-utils.h" + static GtkNotebookClass *parent_class = NULL; static void glade_editor_property_load (GladeEditorProperty *property, GladeWidget *widget); static void glade_editor_property_load_flags (GladeEditorProperty *property); +static void glade_editor_property_load_text (GladeEditorProperty *property); static void glade_editor_class_init (GladeEditorClass *class) @@ -646,6 +648,166 @@ glade_editor_property_show_flags_dialog (GtkWidget *entry, gtk_widget_destroy (dialog); } +static void +glade_editor_property_show_i18n_dialog (GtkWidget *entry, + GladeEditorProperty *property) +{ + GtkWidget *editor; + GtkWidget *dialog; + GtkWidget *vbox, *hbox; + GtkWidget *label; + GtkWidget *sw; + GtkWidget *text_view, *comment_view; + GtkTextBuffer *text_buffer, *comment_buffer; + GtkWidget *translatable_button, *context_button; + const gchar *text; + gint res; + gchar *str; + + g_return_if_fail (property != NULL); + + editor = gtk_widget_get_toplevel (entry); + dialog = gtk_dialog_new_with_buttons (_("Edit Text Property"), + GTK_WINDOW (editor), + GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT, + GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, + GTK_STOCK_OK, GTK_RESPONSE_OK, + NULL); + + gtk_dialog_set_has_separator (GTK_DIALOG (dialog), FALSE); + + vbox = gtk_vbox_new (FALSE, 6); + gtk_widget_show (vbox); + + gtk_container_set_border_width (GTK_CONTAINER (vbox), 8); + + gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog)->vbox), vbox, TRUE, TRUE, 0); + + /* Text */ + label = gtk_label_new_with_mnemonic (_("_Text:")); + gtk_widget_show (label); + gtk_misc_set_alignment (GTK_MISC (label), 0, 0.5); + gtk_box_pack_start (GTK_BOX (vbox), label, FALSE, FALSE, 0); + + sw = gtk_scrolled_window_new (NULL, NULL); + gtk_widget_show (sw); + gtk_box_pack_start (GTK_BOX (vbox), sw, TRUE, TRUE, 0); + gtk_widget_set_size_request (sw, 400, 200); + gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (sw), + GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC); + gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (sw), GTK_SHADOW_IN); + + text_view = gtk_text_view_new (); + gtk_widget_show (text_view); + + gtk_label_set_mnemonic_widget (GTK_LABEL (label), text_view); + + gtk_container_add (GTK_CONTAINER (sw), text_view); + + text_buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (text_view)); + + text = g_value_get_string (property->property->value); + if (text) + { + gtk_text_buffer_set_text (text_buffer, + text, + -1); + } + + /* Translatable and context prefix. */ + hbox = gtk_hbox_new (FALSE, 12); + gtk_widget_show (hbox); + + gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 0); + + translatable_button = gtk_check_button_new_with_mnemonic (_("T_ranslatable")); + gtk_widget_show (translatable_button); + gtk_box_pack_start (GTK_BOX (hbox), translatable_button, FALSE, FALSE, 0); + + gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (translatable_button), + glade_property_i18n_get_translatable (property->property)); + + context_button = gtk_check_button_new_with_mnemonic (_("Has context _prefix")); + gtk_widget_show (context_button); + gtk_box_pack_start (GTK_BOX (hbox), context_button, FALSE, FALSE, 0); + + gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (context_button), + glade_property_i18n_get_has_context (property->property)); + + /* Comments. */ + label = gtk_label_new_with_mnemonic (_("Co_mments for translators:")); + gtk_widget_show (label); + gtk_misc_set_alignment (GTK_MISC (label), 0, 0.5); + gtk_box_pack_start (GTK_BOX (vbox), label, FALSE, FALSE, 0); + + sw = gtk_scrolled_window_new (NULL, NULL); + gtk_widget_show (sw); + gtk_box_pack_start (GTK_BOX (vbox), sw, TRUE, TRUE, 0); + gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (sw), + GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC); + gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (sw), GTK_SHADOW_IN); + + comment_view = gtk_text_view_new (); + gtk_widget_show (comment_view); + + gtk_label_set_mnemonic_widget (GTK_LABEL (label), comment_view); + + gtk_container_add (GTK_CONTAINER (sw), comment_view); + + comment_buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (comment_view)); + + text = glade_property_i18n_get_comment (property->property); + if (text) + { + gtk_text_buffer_set_text (comment_buffer, + text, + -1); + } + + res = gtk_dialog_run (GTK_DIALOG (dialog)); + if (res == GTK_RESPONSE_OK) { + GtkTextIter start, end; + + /* Get the new values. */ + glade_property_i18n_set_translatable ( + property->property, + gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (translatable_button))); + glade_property_i18n_set_has_context ( + property->property, + gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (context_button))); + + /* Text */ + gtk_text_buffer_get_bounds (text_buffer, &start, &end); + str = gtk_text_buffer_get_text (text_buffer, &start, &end, TRUE); + if (str[0] == '\0') + { + g_free (str); + str = NULL; + } + + glade_editor_property_changed_text_common (property->property, str, + property->from_query_dialog); + + g_free (str); + + glade_editor_property_load (property, property->property->widget); + + /* Comment */ + gtk_text_buffer_get_bounds (comment_buffer, &start, &end); + str = gtk_text_buffer_get_text (comment_buffer, &start, &end, TRUE); + if (str[0] == '\0') + { + g_free (str); + str = NULL; + } + + glade_property_i18n_set_comment (property->property, str); + g_free (str); + } + + gtk_widget_destroy (dialog); +} + /* ============================= Create inputs ============================= */ static GtkWidget * glade_editor_create_input_enum_item (GladeEditorProperty *property, @@ -735,9 +897,14 @@ glade_editor_create_input_text (GladeEditorProperty *property) glade_parameter_get_integer (class->parameters, GLADE_TAG_VISIBLE_LINES, &lines); if (lines < 2) { + GtkWidget *hbox; GtkWidget *entry; - + GtkWidget *button; + + hbox = gtk_hbox_new (FALSE, 0); + entry = gtk_entry_new (); + gtk_box_pack_start (GTK_BOX (hbox), entry, TRUE, TRUE, 0); g_signal_connect (G_OBJECT (entry), "activate", G_CALLBACK (glade_editor_property_changed_text), @@ -747,20 +914,41 @@ glade_editor_create_input_text (GladeEditorProperty *property) G_CALLBACK (glade_editor_entry_focus_out), property); - return entry; + if (property->class->translatable) { + button = gtk_button_new_with_label ("..."); + gtk_box_pack_start (GTK_BOX (hbox), button, FALSE, FALSE, 0); + + g_signal_connect (button, "clicked", + G_CALLBACK (glade_editor_property_show_i18n_dialog), + property); + } + + return hbox; } else { - GtkTextView *view; - GtkTextBuffer *buffer; + GtkWidget *hbox; + GtkTextView *view; + GtkWidget *button; + + hbox = gtk_hbox_new (FALSE, 0); view = GTK_TEXT_VIEW (gtk_text_view_new ()); - buffer = gtk_text_view_get_buffer (view); - gtk_text_view_set_editable (view, TRUE); + gtk_box_pack_start (GTK_BOX (hbox), GTK_WIDGET (view), TRUE, TRUE, 0); g_signal_connect (G_OBJECT (view), "focus-out-event", G_CALLBACK (glade_editor_text_view_focus_out), property); - return GTK_WIDGET (view); + + if (property->class->translatable) { + button = gtk_button_new_with_label ("..."); + gtk_box_pack_start (GTK_BOX (hbox), button, FALSE, FALSE, 0); + + g_signal_connect (button, "clicked", + G_CALLBACK (glade_editor_property_show_i18n_dialog), + property); + } + + return hbox; } return NULL; @@ -914,6 +1102,8 @@ glade_editor_append_item_real (GladeEditorTable *table, input = glade_editor_create_input_numeric (property); else if (G_IS_PARAM_SPEC_STRING(property->class->pspec)) input = glade_editor_create_input_text (property); + else if (G_IS_PARAM_SPEC_STRING(property->class->pspec)) + input = glade_editor_create_input_text (property); else if (G_IS_PARAM_SPEC_UNICHAR(property->class->pspec)) input = glade_editor_create_input_unichar (property); @@ -1413,13 +1603,20 @@ glade_editor_property_load_boolean (GladeEditorProperty *property) static void glade_editor_property_load_text (GladeEditorProperty *property) { + GtkBoxChild *child; + GtkWidget *widget; + g_return_if_fail (property != NULL); g_return_if_fail (property->property != NULL); g_return_if_fail (property->property->value != NULL); g_return_if_fail (property->input != NULL); - if (GTK_IS_EDITABLE (property->input)) { - GtkEditable *editable = GTK_EDITABLE (property->input); + /* The entry/textview is the first child. */ + child = GTK_BOX (property->input)->children->data; + widget = child->widget; + + if (GTK_IS_EDITABLE (widget)) { + GtkEditable *editable = GTK_EDITABLE (widget); gint pos, insert_pos = 0; const gchar *text; text = g_value_get_string (property->property->value); @@ -1431,13 +1628,13 @@ glade_editor_property_load_text (GladeEditorProperty *property) g_utf8_strlen (text, -1), &insert_pos); gtk_editable_set_position (editable, pos); - } else if (GTK_IS_TEXT_VIEW (property->input)) { + } else if (GTK_IS_TEXT_VIEW (widget)) { GtkTextBuffer *buffer; const gchar *text; if ((text = g_value_get_string (property->property->value)) != NULL) { - buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (property->input)); + buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (widget)); gtk_text_buffer_set_text (buffer, text, g_utf8_strlen (text, -1)); diff --git a/src/glade-palette.c b/src/glade-palette.c index 438092df..73c69600 100644 --- a/src/glade-palette.c +++ b/src/glade-palette.c @@ -46,6 +46,9 @@ static guint glade_palette_signals[LAST_SIGNAL] = {0}; static GtkWindowClass *parent_class = NULL; +static void glade_palette_append_widget_group (GladePalette *palette, + GladeWidgetGroup *group); + static void glade_palette_class_init (GladePaletteClass *class) { @@ -208,7 +211,8 @@ glade_palette_create_widget_class_button (GladePalette *palette, } static GtkWidget * -glade_palette_widget_table_create (GladePalette *palette, GladeCatalog *catalog) +glade_palette_widget_table_create (GladePalette *palette, + GladeWidgetGroup *group) { GList *list; GtkWidget *sw; @@ -216,7 +220,7 @@ glade_palette_widget_table_create (GladePalette *palette, GladeCatalog *catalog) vbox = gtk_vbox_new (FALSE, 0); - list = glade_catalog_get_widget_classes (catalog); + list = glade_widget_group_get_widget_classes (group); /* Go through all the widget classes in this catalog. */ for (; list; list = list->next) @@ -291,30 +295,24 @@ glade_palette_init (GladePalette *palette) palette->nb_sections = 0; } -/** - * glade_palette_append_catalog: - * @palette: a #GladePalette - * @catalog: a #GladeCatalog - * - * Append @catalog to the @palette. - */ -void -glade_palette_append_catalog (GladePalette *palette, GladeCatalog *catalog) +static void +glade_palette_append_widget_group (GladePalette *palette, + GladeWidgetGroup *group) { gint page; GtkWidget *widget; g_return_if_fail (GLADE_IS_PALETTE (palette)); - g_return_if_fail (catalog != NULL); + g_return_if_fail (group != NULL); page = palette->nb_sections++; /* Add the catalog's title to the GtkComboBox */ gtk_combo_box_append_text (GTK_COMBO_BOX (palette->catalog_selector), - catalog->title); + glade_widget_group_get_title (group)); /* Add the section */ - widget = glade_palette_widget_table_create (palette, catalog); + widget = glade_palette_widget_table_create (palette, group); gtk_notebook_append_page (GTK_NOTEBOOK (palette->notebook), widget, NULL); gtk_widget_show (palette->notebook); @@ -370,8 +368,20 @@ glade_palette_new (GList *catalogs) palette = g_object_new (GLADE_TYPE_PALETTE, NULL); g_return_val_if_fail (palette != NULL, NULL); - for (list = catalogs; list; list = list->next) - glade_palette_append_catalog (palette, GLADE_CATALOG (list->data)); + for (list = catalogs; list; list = list->next) + { + GList *l; + + l = glade_catalog_get_widget_groups (GLADE_CATALOG (list->data)); + for (; l; l = l->next) + { + GladeWidgetGroup *group = GLADE_WIDGET_GROUP (l->data); + + if (glade_widget_group_get_widget_classes (group)) + glade_palette_append_widget_group (palette, + group); + } + } gtk_combo_box_set_active (GTK_COMBO_BOX (palette->catalog_selector), 0); return palette; diff --git a/src/glade-palette.h b/src/glade-palette.h index d85a3585..586e55c8 100644 --- a/src/glade-palette.h +++ b/src/glade-palette.h @@ -72,8 +72,6 @@ GType glade_palette_get_type (void); GladePalette *glade_palette_new (GList *catalogs); -void glade_palette_append_catalog (GladePalette *palette, GladeCatalog *catalog); - void glade_palette_unselect_widget (GladePalette *palette); diff --git a/src/glade-parameter.h b/src/glade-parameter.h index 22a4d08b..972e7d64 100644 --- a/src/glade-parameter.h +++ b/src/glade-parameter.h @@ -19,7 +19,7 @@ G_BEGIN_DECLS <Parameter Key="Default" Value="0"/> <Parameter Key="StepIncrement" Value="1"/> <Parameter Key="PageIncrement" Value="10"/> - <Parameter Key="ClibmRate" Value="1"/> + <Parameter Key="ClimbRate" Value="1"/> </Parameters> </Property> diff --git a/src/glade-project-view.c b/src/glade-project-view.c index 407af947..d41787aa 100644 --- a/src/glade-project-view.c +++ b/src/glade-project-view.c @@ -208,7 +208,10 @@ gpv_find_preceeding_sibling (GtkTreeModel *model, g_return_val_if_fail (GTK_IS_TREE_MODEL (model), NULL); if (!parent_iter) - gtk_tree_model_get_iter_first (model, &next); + { + if (!gtk_tree_model_get_iter_first (model, &next)) + return NULL; + } else { g_return_val_if_fail @@ -216,7 +219,7 @@ gpv_find_preceeding_sibling (GtkTreeModel *model, parent_iter), NULL); gtk_tree_model_iter_children (model, &next, parent_iter); } - + while (42) { gtk_tree_model_get (model, &next, WIDGET_COLUMN, &w, -1); diff --git a/src/glade-property-class.c b/src/glade-property-class.c index bf9b6706..04bd373b 100644 --- a/src/glade-property-class.c +++ b/src/glade-property-class.c @@ -66,6 +66,7 @@ glade_property_class_new (void) property_class->set_function = NULL; property_class->get_function = NULL; property_class->visible = FALSE; + property_class->translatable = TRUE; return property_class; } @@ -476,6 +477,8 @@ glade_property_class_new_from_spec (GParamSpec *spec) { GladePropertyClass *property_class; + g_return_val_if_fail (spec != NULL, NULL); + property_class = glade_property_class_new (); property_class->pspec = spec; @@ -568,7 +571,7 @@ glade_property_class_update_from_node (GladeXmlNode *node, return TRUE; } - visible = glade_xml_get_property_string (node, "Visible"); + visible = glade_xml_get_property_string (node, GLADE_TAG_VISIBLE); if (visible) { if (!g_module_symbol (widget_class->module, visible, (void **) &class->visible)) @@ -595,6 +598,18 @@ glade_property_class_update_from_node (GladeXmlNode *node, /* ... get the tooltip from the pspec ... */ if (class->pspec) class->tooltip = g_strdup (g_param_spec_get_blurb (class->pspec)); + } else { + if (!class->pspec) + { + /* If catalog file didn't specify a pspec function + * and this property isn't fund by introspection + * we simply handle it as a property that has been + * disabled. + */ + glade_property_class_free (class); + *property_class = NULL; + return TRUE; + } } /* ...and the tooltip */ @@ -609,7 +624,7 @@ glade_property_class_update_from_node (GladeXmlNode *node, child = glade_xml_search_child (node, GLADE_TAG_PARAMETERS); if (child) class->parameters = glade_parameter_list_new_from_node (class->parameters, child); - glade_parameter_get_boolean (class->parameters, "Optional", &class->optional); + glade_parameter_get_boolean (class->parameters, GLADE_TAG_OPTIONAL, &class->optional); /* Get the default */ buff = glade_xml_get_property_string (node, GLADE_TAG_DEFAULT); @@ -623,6 +638,11 @@ glade_property_class_update_from_node (GladeXmlNode *node, return FALSE; } + /* 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); + /* common, optional, etc */ class->common = glade_xml_get_property_boolean (node, GLADE_TAG_COMMON, FALSE); class->optional = glade_xml_get_property_boolean (node, GLADE_TAG_OPTIONAL, FALSE); diff --git a/src/glade-property-class.h b/src/glade-property-class.h index 5a0873b3..7487ef5c 100644 --- a/src/glade-property-class.h +++ b/src/glade-property-class.h @@ -133,6 +133,11 @@ struct _GladePropertyClass gboolean common; /* Common properties go in the common tab */ gboolean packing; /* Packing properties go in the packing tab */ + gboolean translatable; /* The property should be translatable, which + * means that it needs extra parameters in the + * UI. + */ + gboolean is_modified; /* If true, this property_class has been "modified" from the * the standard property by a xml file. */ diff --git a/src/glade-property.c b/src/glade-property.c index dc41ff6d..354fc6d7 100644 --- a/src/glade-property.c +++ b/src/glade-property.c @@ -55,6 +55,10 @@ glade_property_new (GladePropertyClass *class, GladeWidget *widget, GValue *valu property->value = value; property->enabled = TRUE; + property->i18n_translatable = FALSE; + property->i18n_has_context = FALSE; + property->i18n_comment = NULL; + if (G_IS_PARAM_SPEC_DOUBLE (class->pspec) || G_IS_PARAM_SPEC_FLOAT (class->pspec) || G_IS_PARAM_SPEC_LONG (class->pspec) || @@ -100,10 +104,14 @@ glade_property_dup (GladeProperty *template, GladeWidget *widget) property->widget = widget; property->value = g_new0 (GValue, 1); property->enabled = template->enabled; - + g_value_init (property->value, template->value->g_type); g_value_copy (template->value, property->value); + property->i18n_translatable = template->i18n_translatable; + property->i18n_has_context = template->i18n_has_context; + property->i18n_comment = g_strdup (template->i18n_comment); + return property; } @@ -125,6 +133,8 @@ glade_property_free (GladeProperty *property) property->value = NULL; } + g_free (property->i18n_comment); + g_free (property); } @@ -336,9 +346,59 @@ glade_property_write (GArray *props, GladeProperty *property, GladeInterface *in } } + if (property->class->translatable) + { + /* FIXME: implement writing the i18n metadata. */ + } + info.value = alloc_string(interface, tmp); g_array_append_val (props, info); g_free (tmp); return TRUE; } + +/* Parameters for translatable properties. */ + +void +glade_property_i18n_set_comment (GladeProperty *property, + const gchar *str) +{ + if (property->i18n_comment) + g_free (property->i18n_comment); + + property->i18n_comment = g_strdup (str); +} + +const gchar * +glade_property_i18n_get_comment (GladeProperty *property) +{ + return property->i18n_comment; +} + +void +glade_property_i18n_set_translatable (GladeProperty *property, + gboolean translatable) +{ + property->i18n_translatable = translatable; +} + +gboolean +glade_property_i18n_get_translatable (GladeProperty *property) +{ + return property->i18n_translatable; +} + +void +glade_property_i18n_set_has_context (GladeProperty *property, + gboolean has_context) +{ + property->i18n_has_context = has_context; +} + +gboolean +glade_property_i18n_get_has_context (GladeProperty *property) +{ + return property->i18n_has_context; +} + diff --git a/src/glade-property.h b/src/glade-property.h index b0850a92..b39f2888 100644 --- a/src/glade-property.h +++ b/src/glade-property.h @@ -33,6 +33,12 @@ struct _GladeProperty * of the property->input state for the loaded * widget. */ + + /* Used only for translatable strings. */ + gboolean i18n_translatable; + gboolean i18n_has_context; + gchar *i18n_comment; + #if 0 GladeWidget *child; /* A GladeProperty of type object has a child */ #endif @@ -55,6 +61,18 @@ gboolean glade_property_write (GArray *props, GladeProperty *property, GladeProperty *glade_property_dup (GladeProperty *template, GladeWidget *widget); +void glade_property_i18n_set_comment (GladeProperty *property, const gchar *str); + +const gchar *glade_property_i18n_get_comment (GladeProperty *property); + +void glade_property_i18n_set_translatable (GladeProperty *property, gboolean translatable); + +gboolean glade_property_i18n_get_translatable (GladeProperty *property); + +void glade_property_i18n_set_has_context (GladeProperty *property, gboolean has_context); + +gboolean glade_property_i18n_get_has_context (GladeProperty *property); + G_END_DECLS #endif /* __GLADE_PROPERTY_H__ */ diff --git a/src/glade-types.h b/src/glade-types.h index 05153684..93299592 100644 --- a/src/glade-types.h +++ b/src/glade-types.h @@ -26,6 +26,7 @@ typedef struct _GladeProjectViewTree GladeProjectViewTree; typedef struct _GladeProjectWindow GladeProjectWindow; typedef struct _GladeCatalog GladeCatalog; +typedef struct _GladeWidgetGroup GladeWidgetGroup; typedef struct _GladeCursor GladeCursor; typedef struct _GladePlaceholder GladePlaceholder; diff --git a/src/glade-widget-class.c b/src/glade-widget-class.c index 3353718a..d3e8af8b 100644 --- a/src/glade-widget-class.c +++ b/src/glade-widget-class.c @@ -1,6 +1,7 @@ /* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ /* * Copyright (C) 2001 Ximian, Inc. + * Copyright (C) 2004 Imendio AB * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as @@ -484,39 +485,14 @@ glade_widget_class_update_children_from_node (GladeXmlNode *node, } } -/** - * glade_widget_class_extend_with_file: - * @filename: complete path name of the xml file with the description of the - * #GladeWidgetClass - * - * This function extends an existing GladeWidgetClass with the data found on - * the file with name @filename (if it exists). Notably, it will add new - * properties to the #GladeWidgetClass, or modify existing ones, in function - * of the contents of the file. - * - * Returns: %TRUE if the file exists and its format is correct, %FALSE otherwise - */ static gboolean -glade_widget_class_extend_with_file (GladeWidgetClass *widget_class, const char *filename) +glade_widget_class_extend_with_node (GladeWidgetClass *widget_class, + GladeXmlNode *node) { - GladeXmlContext *context; - GladeXmlDoc *doc; - GladeXmlNode *properties; - GladeXmlNode *node; - - g_return_val_if_fail (filename != NULL, FALSE); - - context = glade_xml_context_new_from_path - (filename, NULL, GLADE_TAG_GLADE_WIDGET_CLASS); - if (!context) - return FALSE; - - doc = glade_xml_context_get_doc (context); - node = glade_xml_doc_get_root (doc); - if (!doc || !node) { - glade_xml_context_destroy (context); - return FALSE; - } + GladeXmlNode *child; + + g_return_val_if_fail (widget_class != NULL, FALSE); + g_return_val_if_fail (node != NULL, FALSE); if (widget_class->module) { @@ -537,16 +513,21 @@ glade_widget_class_extend_with_file (GladeWidgetClass *widget_class, const char /* if we found a <properties> tag on the xml file, we add the properties * that we read from the xml file to the class. */ - properties = glade_xml_search_child (node, GLADE_TAG_PROPERTIES); - if (properties) - glade_widget_class_update_properties_from_node - (properties, widget_class, &widget_class->properties); + child = glade_xml_search_child (node, GLADE_TAG_PROPERTIES); + if (child) + { + glade_widget_class_update_properties_from_node (child, + widget_class, + &widget_class->properties); + } - properties = glade_xml_search_child (node, GLADE_TAG_CHILDREN); - if (properties) - glade_widget_class_update_children_from_node (properties, widget_class); + child = glade_xml_search_child (node, GLADE_TAG_CHILDREN); + if (child) + { + glade_widget_class_update_children_from_node (child, + widget_class); + } - glade_xml_context_destroy (context); return TRUE; } @@ -852,85 +833,78 @@ glade_widget_class_direct_children (GtkWidget *ancestor, GtkWidget *widget, cons return FALSE; } -/** - * glade_widget_class_new: - * @name: name of the widget class (for instance: GtkButton) - * @generic_name: base of the name for the widgets of this class - * (for instance: button). This parameter is optional. For - * abstract classes there is no need to supply a generic_name. - * @base_filename: filename containing a further description of the widget, - * without the directory (optional). - * - * Creates a new #GladeWidgetClass, initializing it with the - * name, generic_name and base_filename. - * - * The widget class will be first build using the information that the GLib - * object system returns, and then it will be expanded (optionally) with the - * information contained on the xml filename. - * - * Returns: a new #GladeWidgetClass, or %NULL if there are any errors - */ GladeWidgetClass * -glade_widget_class_new (const char *name, - const char *generic_name, - const char *palette_name, - const char *base_filename, - const char *base_library) +glade_widget_class_new (GladeXmlNode *class_node, const gchar *library) { - GladeWidgetClass *widget_class = NULL; - char *filename = NULL; - char *init_function_name = NULL; - GModule *module = NULL; - GType parent_type; - - g_return_val_if_fail (name != NULL, NULL); - - if (glade_widget_class_get_by_name (name) != NULL) + GladeWidgetClass *widget_class; + gchar *name; + gchar *generic_name; + gchar *title; + GModule *module; + GType parent_type; + + if (!glade_xml_node_verify (class_node, GLADE_TAG_GLADE_WIDGET_CLASS)) { - g_warning ("The widget class [%s] has at least two different definitions.\n", - name); - goto lblError; + g_warning ("Widget class node is not '%s'", + GLADE_TAG_GLADE_WIDGET_CLASS); + return NULL; + } + + name = glade_xml_get_property_string (class_node, GLADE_TAG_NAME); + if (!name) + { + g_warning ("Required property 'name' not found in '%s'", + GLADE_TAG_GLADE_WIDGET_CLASS); + return NULL; } - if (base_filename != NULL) + if (glade_widget_class_get_by_name (name)) { - filename = g_strconcat (glade_widgets_dir, "/", base_filename, NULL); - if (filename == NULL) - { - g_warning (_("Not enough memory.")); - goto lblError; - } + g_warning ("Widget class '%s' already defined", name); + + g_free (name); + return NULL; } - if (base_library != NULL) + generic_name = glade_xml_get_property_string (class_node, + GLADE_TAG_GENERIC_NAME); + title = glade_xml_get_property_string (class_node, GLADE_TAG_TITLE); + + module = NULL; + if (library) { - module = glade_widget_class_load_library (base_library); + module = glade_widget_class_load_library (library); if (!module) - goto lblError; + { + g_warning ("Failed to load external library '%s'", + library); + g_free (name); + g_free (generic_name); + g_free (title); + return NULL; + } } - + widget_class = g_new0 (GladeWidgetClass, 1); + widget_class->name = name; + widget_class->module = module; + widget_class->generic_name = generic_name; + widget_class->palette_name = title; + widget_class->in_palette = title ? TRUE : FALSE; - widget_class->module = module; - - widget_class->generic_name = generic_name ? g_strdup (generic_name) : NULL; - widget_class->palette_name = palette_name ? g_strdup (palette_name) : NULL; - widget_class->name = g_strdup (name); - widget_class->in_palette = palette_name ? TRUE : FALSE; - - widget_class->type = glade_util_get_type_from_name (widget_class->name); + widget_class->type = glade_util_get_type_from_name (name); if (widget_class->type == 0) - goto lblError; - + { + glade_widget_class_free (widget_class); + return NULL; + } + widget_class->properties = glade_widget_class_list_properties (widget_class); widget_class->signals = glade_widget_class_list_signals (widget_class); widget_class->children = glade_widget_class_list_children (widget_class); widget_class->icon = glade_widget_class_create_icon (widget_class); - widget_class->child_property_applies = glade_widget_class_direct_children; - g_free (init_function_name); - for (parent_type = g_type_parent (widget_class->type); parent_type != 0; parent_type = g_type_parent (parent_type)) @@ -945,29 +919,19 @@ glade_widget_class_new (const char *name, glade_widget_class_merge (widget_class, parent_class); } } - - /* if there is an associated filename, then open and parse it */ - if (filename != NULL) - glade_widget_class_extend_with_file (widget_class, filename); - - g_free (filename); - + + if (glade_xml_node_get_children (class_node)) + glade_widget_class_extend_with_node (widget_class, class_node); + /* store the GladeWidgetClass on the cache, * if it's the first time we store a widget class, then * initialize the global widget_classes hash. */ if (!widget_classes) widget_classes = g_hash_table_new (g_str_hash, g_str_equal); - g_hash_table_insert (widget_classes, widget_class->name, widget_class); - + return widget_class; - -lblError: - g_free (filename); - g_free (init_function_name); - glade_widget_class_free (widget_class); - return NULL; } /** diff --git a/src/glade-widget-class.h b/src/glade-widget-class.h index 4bd4143f..64edd0dc 100644 --- a/src/glade-widget-class.h +++ b/src/glade-widget-class.h @@ -140,12 +140,8 @@ struct _GladeWidgetClassSignal }; -GladeWidgetClass *glade_widget_class_new (const char *name, - const char *generic_name, - const char *palette_name, - const char *base_filename, - const char *base_library); -GladeWidgetClass *glade_widget_class_new_from_node (GladeXmlNode *node); +GladeWidgetClass *glade_widget_class_new (GladeXmlNode *class_node, + const gchar *library); void glade_widget_class_free (GladeWidgetClass *widget_class); GladeWidgetClass *glade_widget_class_get_by_name (const char *name); GladeWidgetClass *glade_widget_class_get_by_type (GType type); diff --git a/src/glade-widget.c b/src/glade-widget.c index da7441d8..54d96178 100644 --- a/src/glade-widget.c +++ b/src/glade-widget.c @@ -1841,7 +1841,7 @@ glade_widget_value_from_prop_info (GladePropInfo *info, GladePropertyClass *pclass; GValue *gvalue = NULL; gchar *id; - + g_return_val_if_fail (info != NULL, NULL); id = g_strdup (info->name); @@ -1870,6 +1870,7 @@ glade_widget_apply_property_from_prop_info (GladePropInfo *info, g_return_val_if_fail (widget != NULL, FALSE); id = g_strdup (info->name); + glade_util_replace (id, '_', '-'); property = glade_widget_get_property (widget, id); g_free (id); @@ -1952,9 +1953,12 @@ glade_widget_fill_from_widget_info (GladeWidgetInfo *info, } static GValue * -glade_widget_get_property_from_widget_info (GladeWidgetClass *class, - GladeWidgetInfo *info, - const gchar *name) +glade_widget_get_property_from_widget_info (GladeWidgetClass *class, + GladeWidgetInfo *info, + const gchar *name, + gboolean *translatable, + gboolean *has_context, + gchar **comment) { GValue *value = NULL; gint i; @@ -1970,6 +1974,18 @@ glade_widget_get_property_from_widget_info (GladeWidgetClass *class, if (!strcmp (id, name)) { g_free (id); + + /* FIXME: Waiting for a solution in libglade for i18n + * metadata. + */ + + if (translatable) + *translatable = FALSE; /*pinfo->translatable;*/ + if (has_context) + *has_context = FALSE; /*pinfo->has_context;*/ + if (comment) + *comment = NULL; /*g_strdup (pinfo->comment);*/ + return glade_widget_value_from_prop_info (pinfo, class); } g_free (id); @@ -2000,15 +2016,32 @@ glade_widget_properties_from_widget_info (GladeWidgetClass *class, GladePropertyClass *pclass = list->data; GValue *value; GladeProperty *property; + gboolean translatable; + gboolean has_context; + gchar *comment = NULL; /* If there is a value in the XML, initialize property with it, * otherwise initialize property to default. */ - value = glade_widget_get_property_from_widget_info - (class, info, pclass->id); + value = glade_widget_get_property_from_widget_info (class, + info, + pclass->id, + &translatable, + &has_context, + &comment); + property = glade_property_new (pclass, NULL, value); property->enabled = value ? TRUE : property->enabled; - properties = g_list_prepend (properties, property); + + if (value) { + glade_property_i18n_set_translatable (property, translatable); + glade_property_i18n_set_has_context (property, has_context); + glade_property_i18n_set_comment (property, comment); + } + + g_free (comment); + + properties = g_list_prepend (properties, property); } return g_list_reverse (properties); } @@ -2044,7 +2077,8 @@ glade_widget_params_from_widget_info (GladeWidgetClass *widget_class, /* Try filling parameter with value from widget info. */ if ((value = glade_widget_get_property_from_widget_info - (widget_class, info, parameter.name)) != NULL) + (widget_class, info, parameter.name, + NULL, NULL, NULL)) != NULL) { if (g_value_type_compatible (G_VALUE_TYPE (value), G_VALUE_TYPE (¶meter.value))) diff --git a/src/glade.h b/src/glade.h index e7ab35ce..0fe917e2 100644 --- a/src/glade.h +++ b/src/glade.h @@ -40,31 +40,13 @@ #include "glade-xml-utils.h" #define GLADE_PATH_SEP_STR "/" -#define GLADE_TAG_GLADE_WIDGET_CLASS "GladeWidgetClass" #define GLADE_TAG_GET_TYPE_FUNCTION "GetTypeFunction" -#define GLADE_TAG_GENERIC_NAME "GenericName" -#define GLADE_TAG_NAME "Name" -#define GLADE_TAG_ID "Id" -#define GLADE_TAG_KEY "Key" -#define GLADE_TAG_VALUE "Value" #define GLADE_TAG_TOPLEVEL "Toplevel" #define GLADE_TAG_PLACEHOLDER "Placeholder" #define GLADE_TAG_ICON "Icon" -#define GLADE_TAG_PROPERTIES "Properties" #define GLADE_TAG_CHILD_PROPERTIES "ChildProperties" -#define GLADE_TAG_CHILD "Child" -#define GLADE_TAG_CHILDREN "Children" #define GLADE_TAG_CONTAINER "Container" -#define GLADE_TAG_PROPERTY "Property" -#define GLADE_TAG_COMMON "Common" -#define GLADE_TAG_OPTIONAL "Optional" -#define GLADE_TAG_OPTIONAL_DEFAULT "OptionalDefault" -#define GLADE_TAG_TYPE "Type" -#define GLADE_TAG_SPEC "Spec" -#define GLADE_TAG_TOOLTIP "Tooltip" #define GLADE_TAG_GTKARG "GtkArg" -#define GLADE_TAG_PARAMETERS "Parameters" -#define GLADE_TAG_PARAMETER "Parameter" #define GLADE_TAG_SYMBOL "Symbol" #define GLADE_TAG_ENUM "Enum" #define GLADE_TAG_ENUMS "Enums" @@ -82,33 +64,13 @@ #define GLADE_TAG_CHOICE "Choice" #define GLADE_TAG_OTHER_WIDGETS "OtherWidgets" #define GLADE_TAG_OBJECT "Object" -#define GLADE_TAG_SET_FUNCTION "SetFunction" -#define GLADE_TAG_GET_FUNCTION "GetFunction" -#define GLADE_TAG_VERIFY_FUNCTION "VerifyFunction" -#define GLADE_TAG_QUERY "Query" #define GLADE_TAG_QUESTION "Question" #define GLADE_TAG_VISIBLE_LINES "VisibleLines" #define GLADE_ENUM_DATA_TAG "GladeEnumDataTag" #define GLADE_FLAGS_DATA_TAG "GladeFlagsDataTag" -#define GLADE_TAG_SIGNAL_NAME "SignalName" -#define GLADE_TAG_DEFAULT "Default" -#define GLADE_TAG_DISABLED "Disabled" -#define GLADE_TAG_REPLACE_CHILD_FUNCTION "ReplaceChildFunction" -#define GLADE_TAG_POST_CREATE_FUNCTION "PostCreateFunction" -#define GLADE_TAG_FILL_EMPTY_FUNCTION "FillEmptyFunction" -#define GLADE_TAG_GET_INTERNAL_CHILD_FUNCTION "GetInternalChildFunction" -#define GLADE_TAG_ADD_CHILD_FUNCTION "AddChildFunction" -#define GLADE_TAG_REMOVE_CHILD_FUNCTION "RemoveChildFunction" -#define GLADE_TAG_GET_CHILDREN_FUNCTION "GetChildrenFunction" -#define GLADE_TAG_GET_ALL_CHILDREN_FUNCTION "GetAllChildrenFunction" -#define GLADE_TAG_CHILD_SET_PROP_FUNCTION "ChildSetPropertyFunction" -#define GLADE_TAG_CHILD_GET_PROP_FUNCTION "ChildGetPropertyFunction" #define GLADE_TAG_IN_PALETTE "InPalette" -#define GLADE_TAG_CATALOG "GladeCatalog" -#define GLADE_TAG_GLADE_WIDGET "GladeWidget" -#define GLADE_TAG_CHILD_PROPERTY_APPLIES_FUNCTION "ChildPropertyApplies" #define GLADE_TAG_EVENT_HANDLER_CONNECTED "EventHandlerConnected" #define GLADE_MODIFY_PROPERTY_DATA "GladeModifyPropertyData" @@ -129,6 +91,53 @@ #define GLADE_XML_TAG_PLACEHOLDER "placeholder" #define GLADE_XML_TAG_INTERNAL_CHILD "internal-child" +/* Used for catalog tags and attributes */ +#define GLADE_TAG_GLADE_CATALOG "glade-catalog" +#define GLADE_TAG_GLADE_WIDGET_CLASSES "glade-widget-classes" +#define GLADE_TAG_GLADE_WIDGET_CLASS "glade-widget-class" +#define GLADE_TAG_GLADE_WIDGET_GROUP "glade-widget-group" +#define GLADE_TAG_GLADE_WIDGET_CLASS_REF "glade-widget-class-ref" + +#define GLADE_TAG_SIGNAL_NAME "signal-name" +#define GLADE_TAG_DEFAULT "default" +#define GLADE_TAG_DISABLED "disabled" +#define GLADE_TAG_REPLACE_CHILD_FUNCTION "replace-child-function" +#define GLADE_TAG_POST_CREATE_FUNCTION "post-create-function" +#define GLADE_TAG_FILL_EMPTY_FUNCTION "fill-empty-function" +#define GLADE_TAG_GET_INTERNAL_CHILD_FUNCTION "get-internal-child-function" +#define GLADE_TAG_ADD_CHILD_FUNCTION "add-child-function" +#define GLADE_TAG_REMOVE_CHILD_FUNCTION "remove-child-function" +#define GLADE_TAG_GET_CHILDREN_FUNCTION "get-children-function" +#define GLADE_TAG_GET_ALL_CHILDREN_FUNCTION "get-all-children-function" +#define GLADE_TAG_CHILD_SET_PROP_FUNCTION "child-set-property-function" +#define GLADE_TAG_CHILD_GET_PROP_FUNCTION "child-get-property-function" +#define GLADE_TAG_CHILD_PROPERTY_APPLIES_FUNCTION "child-property-applies-function" +#define GLADE_TAG_PROPERTIES "properties" +#define GLADE_TAG_PROPERTY "property" +#define GLADE_TAG_TYPE "type" +#define GLADE_TAG_SPEC "spec" +#define GLADE_TAG_TOOLTIP "tooltip" +#define GLADE_TAG_PARAMETERS "parameters" +#define GLADE_TAG_PARAMETER "parameter" +#define GLADE_TAG_SET_FUNCTION "set-function" +#define GLADE_TAG_GET_FUNCTION "get-function" +#define GLADE_TAG_VERIFY_FUNCTION "verify-function" +#define GLADE_TAG_QUERY "query" +#define GLADE_TAG_COMMON "common" +#define GLADE_TAG_OPTIONAL "optional" +#define GLADE_TAG_OPTIONAL_DEFAULT "optional-default" +#define GLADE_TAG_VISIBLE "visible" +#define GLADE_TAG_GENERIC_NAME "generic-name" +#define GLADE_TAG_NAME "name" +#define GLADE_TAG_TITLE "title" +#define GLADE_TAG_LIBRARY "library" +#define GLADE_TAG_ID "id" +#define GLADE_TAG_KEY "key" +#define GLADE_TAG_VALUE "value" +#define GLADE_TAG_CHILD "child" +#define GLADE_TAG_CHILDREN "children" +#define GLADE_TAG_TRANSLATABLE "translatable" + extern gboolean verbose; extern gchar* glade_data_dir; @@ -124,8 +124,11 @@ glade_init (void) glade_cursor_init (); catalogs = glade_catalog_load_all (); - if (!catalogs) + if (!catalogs) + { + g_warning ("Couldn't load any catalogs"); return FALSE; + } project_window = glade_project_window_new (catalogs); diff --git a/widgets/Makefile.am b/widgets/Makefile.am index 0e44596a..d6cc991f 100644 --- a/widgets/Makefile.am +++ b/widgets/Makefile.am @@ -1,39 +1,6 @@ catalogs_DATA = \ - glade-palette.xml \ - gtk-base.xml \ - gtk-additional.xml \ - gtk-dialogs.xml \ - gtk-obsolete.xml - -widgets_DATA = \ - gtkaccellabel.xml \ - gtkbox.xml \ - gtkbutton.xml \ - gtkcheckbutton.xml \ - gtkcontainer.xml \ - gtkdialog.xml \ - gtkfixed.xml \ - gtkframe.xml \ - gtkhandlebox.xml \ - gtklabel.xml \ - gtkmenubar.xml \ - gtkmessagedialog.xml \ - gtknotebook.xml \ - gtkoptionmenu.xml \ - gtkpaned.xml \ - gtkprogressbar.xml \ - gtkradiobutton.xml \ - gtkruler.xml \ - gtkspinbutton.xml \ - gtkstatusbar.xml \ - gtktable.xml \ - gtktogglebutton.xml \ - gtktreeview.xml \ - gtktoolbar.xml \ - gtkwidget.xml \ - gtkwindow.xml + gtk+.xml EXTRA_DIST = \ - $(catalogs_DATA) \ - $(widgets_DATA) + $(catalogs_DATA) diff --git a/widgets/adding-widgets.txt b/widgets/adding-widgets.txt new file mode 100644 index 00000000..e1a0a257 --- /dev/null +++ b/widgets/adding-widgets.txt @@ -0,0 +1,219 @@ +This document describes how to add widgets to Glade +--------------------------------------------------- + +The widgets that are available in the Glade UI builder are handled in a +dynamic way and additional widgets can be added, for example from other +libraries, by installing a widget plugin. + +A widget plugin consists of a catalog file and a shared library and +icons for the widgets to use in the widget palette. + +The catalog file is written in an XML format that will be described +below. There is also a DTD for the format which can be found in XXX. + +Many properties of widgets can be handled automatically by the GObject +introspection features. Not all of them can though, and advanced widgets +often also need additional support from code. This is specified in the +catalog file, where you can override default values, hide properties, +specify functions to call in the installed plugin, etc. + +The catalog file is also used to group the widgets in groups that +correspond to the groups in the Glade widget palette. You can also +specify which property page each property should be displayed on +(e.g. the "common" page or the "packing" page). + +*** FIXME: check if above is really possible, and how it's done. + +In theory, the catalog file should be enough, but most widgets also need +supporting code to be usable in Glade, which is where the plugin library +comes in. An example of both a catalog file and plugin library can be +found in the Glade sources, since the GTK+ widget set that is supported +by default in Glade also is implemented this way. The catalog file is +located in widgets/gtk+.xml, and the source code in src/glade-gtk.c. The +catalog file starts by specifying the name of the catalog and the plugin +library to use: + +<glade-catalog name="gtk+" library="gladegtk"> + <glade-widget-classes> + + ... widgets go here + + +Widgets +------- + +Let's look at the XML for a simple widget, GtkLabel: + + <glade-widget-class name="GtkLabel" generic-name="label" title="Label"> + ... + </glade-widget-class> + +The name is the class name of the widget. Generic name is used to get +the icon name for the widget palette, and is a regular icon theme +icon. The generic name is also used to generate a default name for +instances of the widget in the UI editor. + + +Properties +---------- + +Let's expand the example from above: + + <glade-widget-class name="GtkLabel" generic-name="label" title="Label"> + <properties> + <property id="label" default="label"/> + <property id="pattern" default=""/> + </properties> + </glade-widget-class> + +The default values of two properties, label and pattern, have been +overridden. + +You can also mark a property as optional, in which case there is a +checkbutton displayed next to it in the editor and the property will +only be set if the checkbutton is enabled: + + <property id="my-property" optional="True" optional-default="False" default="my-value"/> + +The "optional-default" parameter specifies if the checkbutton should be +checked or not by default. An example of "optional" is used is the +default width and height of a window where you sometimes don't want to +set a value. + +Normally, the tooltip for the property is retrieved through GObject +introspection but if for some reason the value is not usable, it can be +overridden: + + <property id="label" default="label"/> + <tooltip>A tooltip for this property</tooltip> + </property> + +Some widgets need special handling for properties with support code in +the plugin library. The functions available are: + + <property ...> + <set-function>my_widget_set_my_property</set-function> + <get-function>my_widget_get_my_property</get-function> + <verify-function>my_widget_verify_my_property</verify-function> + </property> + +Set and get should be self-explanatory, and the verify function is used +to verify that the value the user has entered is OK. + +There is also a function for deciding if a property should be shown in +the UI or not, conditionally: + +*** FIXME: check why visible is a parameter instead of a tag. + + <property id="tooltip" name="tooltip" visible="glade_gtk_widget_condition"> + +The main use for this is to hide properties for certain sub-classes +where they don't make sense. + +For properties where the type needs to be special-cased in the editor, +for example like the size property of a container which isn't a real +GObject property, the GParamSpec constructor can be specified: + + <property ...> + <spec>my_param_spec</spec> + </property> + +*** FIXME: Shouldn't this be called spec-function for consistency? + +*** FIXME: write about common="True/False", other notebook pages? + +The functions listed should have the following signatures: + +void set_function (GObject *object, GValue *value); +void get_function (GObject *object, GValue *value); +gboolean verify_function (GObject *object, GValue *value); +GParamSpec *spec_function (void); +gboolean visible_function (GladeWidgetClass *klass); + + +Querying the user +----------------- + +Some properties might make sense to query the user for before creating a +widget. This is used for instance for the size of boxes and number of +buttons in a dialog. To achieve this, simply set the query parameter of +the property: + + <property id="my-property" default="1" query="True"> + ... + </property> + + +Property parameters +------------------- + +Properties can have additional parameters that affect the behavior of +them in the editor. For numeric properties this lets you set the +behavior of the spinbutton used to enter the value. Example: + + <property id="n-rows" default="3" query="True"> + <parameters> + <parameter key="Min" value="1"/> + <parameter key="Max" value="10000"/> + <parameter key="StepIncrement" value="1"/> + <parameter key="PageIncrement" value="10"/> + <parameter key="ClimbRate" value="1"/> + </parameters> + </property> + +*** FIXME: Are there parameters for strings etc? + + +Container widgets +----------------- + +*** FIXME: child properties, packing, functions, ... + + +Grouping +-------- + +The widgets are groups in different groups in the Glade UI. Those groups +are defined in the catalog file as follows: + + <glade-widget-group name="my-widgets" title="My widgets"> + <glade-widget-class-ref name="MyFirstWidget"/> + <glade-widget-class-ref name="MysecondWidget"/> + + ... + </glade-widget-group> + + +The file should contain one or more widgets groups. + + +Validating the catalog file +--------------------------- + +The DTD that is shipped with Glade can be used to validate your catalog +file. Note that properties must be entered in the same order as they are +specified in the DTD for the validation to pass. + +To validate a fil, do this: + + xmllint --dtdvalid glade-catalog.dtd --noout my-catalog.xml + + + +Installing a plugin +------------------- + +To install a widget plugin, the catalog XML file should be copied into +the catalog directory: + + $(datadir)/glade-3/catalogs + +*** FIXME: Fix the version to be like this. + +The plugin library should be installed into the modules directory: + + $(libdir)/glade/ + +*** FIXME: Shouldn't this be glade-3 for consistency? + + diff --git a/widgets/glade-catalog.dtd b/widgets/glade-catalog.dtd new file mode 100644 index 00000000..71b66041 --- /dev/null +++ b/widgets/glade-catalog.dtd @@ -0,0 +1,90 @@ +<?xml version ='1.0' encoding='UTF-8'?> + +<!ELEMENT glade-catalog (glade-widget-classes?, + glade-widget-group*)> + +<!ATTLIST glade-catalog name CDATA #REQUIRED + library CDATA #IMPLIED + requires CDATA #IMPLIED> + +<!ELEMENT glade-widget-classes (glade-widget-class*)> + +<!ELEMENT glade-widget-class (post-create-function?, + get-internal-child-function?, + child-property-applies-function?, + properties?, + children?)> + +<!ATTLIST glade-widget-class name CDATA #REQUIRED + generic-name CDATA #IMPLIED + title CDATA #IMPLIED> + +<!ELEMENT properties (property+)> + +<!ELEMENT property (spec?, + type?, + tooltip?, + parameters?, + set-function?, + get-function?, + verify-function?)> + +<!ATTLIST property id CDATA #REQUIRED + name CDATA #IMPLIED + default CDATA #IMPLIED + query CDATA #IMPLIED + common CDATA #IMPLIED + disabled CDATA #IMPLIED + visible CDATA #IMPLIED + optional CDATA #IMPLIED + optional-default CDATA #IMPLIED + translatable CDATA #IMPLIED> + +<!ELEMENT set-function (#PCDATA)> +<!ELEMENT get-function (#PCDATA)> +<!ELEMENT spec (#PCDATA)> +<!ELEMENT tooltip (#PCDATA)> +<!ELEMENT verify-function (#PCDATA)> + +<!ELEMENT parameters (parameter+)> + +<!ELEMENT parameter EMPTY> + +<!ATTLIST parameter key CDATA #REQUIRED + value CDATA #REQUIRED> + +<!ELEMENT children (child+)> + +<!ELEMENT child (type, + add-child-function?, + remove-child-function?, + get-children-function?, + get-all-children-function?, + set-property-function?, + get-property-function?, + replace-child-function?, + fill-empty-function?, + properties?)> + +<!ELEMENT type (#PCDATA)> +<!ELEMENT add-child-function (#PCDATA)> +<!ELEMENT remove-child-function (#PCDATA)> +<!ELEMENT get-children-function (#PCDATA)> +<!ELEMENT get-all-children-function (#PCDATA)> +<!ELEMENT set-prop-function (#PCDATA)> +<!ELEMENT get-prop-function (#PCDATA)> +<!ELEMENT fill-empty-function (#PCDATA)> +<!ELEMENT replace-child-function (#PCDATA)> + +<!ELEMENT post-create-function (#PCDATA)> +<!ELEMENT get-internal-child-function (#PCDATA)> +<!ELEMENT child-property-applies-function (#PCDATA)> + +<!ELEMENT glade-widget-group (glade-widget-class-ref+)> + +<!ATTLIST glade-widget-group name CDATA #REQUIRED + title CDATA #REQUIRED> + +<!ELEMENT glade-widget-class-ref EMPTY> +<!ATTLIST glade-widget-class-ref name CDATA #REQUIRED> + diff --git a/widgets/gtk+.xml.in b/widgets/gtk+.xml.in new file mode 100644 index 00000000..fcf6b9a1 --- /dev/null +++ b/widgets/gtk+.xml.in @@ -0,0 +1,520 @@ +<glade-catalog name="gtk+" library="gladegtk"> + <glade-widget-classes> + <!-- Gtk+ Base --> + <glade-widget-class name="GtkWidget"> + <properties> + <property common="True" id="visible"> + <set-function>ignore</set-function> + <get-function>ignore</get-function> + </property> + + <property common="True" optional="True" optional-default="False" default="0" id="width-request"/> + + <property common="True" optional="True" optional-default="False" default="0" id="height-request"/> + + <property common="True" id="tooltip" name="Tooltip" visible="glade_gtk_widget_condition" default=""> + <spec>glade_gtk_standard_string_spec</spec> + <set-function>glade_gtk_widget_set_tooltip</set-function> + <get-function>glade_gtk_widget_get_tooltip</get-function> + </property> + + <property common="True" id="events"> + <set-function>ignore</set-function> + <get-function>ignore</get-function> + </property> + <property id="name" translatable="False"/> + </properties> + </glade-widget-class> + + <glade-widget-class name="GtkContainer"> + <children> + <child> + <type>GtkWidget</type> + <replace-child-function>glade_gtk_container_replace_child</replace-child-function> + <fill-empty-function>glade_gtk_container_fill_empty</fill-empty-function> + </child> + </children> + </glade-widget-class> + + <glade-widget-class name="GtkBox"> + <properties> + <property id="size" name="Number of items" query="TRUE" default="3"> + <spec>glade_gtk_standard_int_spec</spec> + <tooltip>The number of items in the box</tooltip> + <parameters> + <parameter key="Min" value="1"/> + <parameter key="Max" value="10000"/> + <parameter key="StepIncrement" value="1"/> + <parameter key="PageIncrement" value="10"/> + <parameter key="ClimbRate" value="1"/> + </parameters> + <set-function>glade_gtk_box_set_size</set-function> + <get-function>glade_gtk_box_get_size</get-function> + <verify-function>glade_gtk_box_verify_size</verify-function> + </property> + </properties> + + <children> + <child> + <type>GtkWidget</type> + <fill-empty-function>empty</fill-empty-function> + </child> + </children> + </glade-widget-class> + + <glade-widget-class name="GtkPaned"> + <children> + <child> + <type>GtkWidget</type> + <fill-empty-function>glade_gtk_paned_fill_empty</fill-empty-function> + </child> + </children> + </glade-widget-class> + + <glade-widget-class name="GtkWindow" generic-name="window" title="Window"> + <post-create-function>glade_gtk_window_post_create</post-create-function> + + <properties> + + <property id="modal"> + <set-function>ignore</set-function> + <get-function>ignore</get-function> + </property> + <property id="default-width" default="0" optional="True" optional-default="False"/> + <property id="default-height" default="0" optional="True" optional-default="False"/> + <property id="type-hint"> + <set-function>ignore</set-function> + <get-function>ignore</get-function> + </property> + <property id="type"> + <set-function>ignore</set-function> + <get-function>ignore</get-function> + </property> + <property id="allow-shrink" disabled="TRUE" /> + <property id="allow-grow" disabled="TRUE" /> + <property id="resize-mode" disabled="TRUE" /> + <property id="role" translatable="False"/> + <property id="icon-name" translatable="False"/> + </properties> + </glade-widget-class> + + <glade-widget-class name="GtkMenuBar" generic-name="menubar" title="Menu Bar"> + <!-- menubar is a container you can't add placeholders to it --> + <children> + <child> + <type>GtkWidget</type> + <fill-empty-function>empty</fill-empty-function> + </child> + </children> + </glade-widget-class> + + <glade-widget-class name="GtkToolbar" generic-name="toolbar" title="Tool Bar"> + <properties> + + <property id="size" name="Size" default="3" query="TRUE"> + <spec>glade_gtk_standard_int_spec</spec> + <tooltip>The number of items in the toolbar</tooltip> + <parameters> + <parameter key="Min" value="0"/> + <parameter key="Max" value="10000"/> + <parameter key="StepIncrement" value="1"/> + <parameter key="PageIncrement" value="10"/> + <parameter key="ClimbRate" value="1"/> + </parameters> + <set-function>glade_gtk_toolbar_set_size</set-function> + <get-function>glade_gtk_toolbar_get_size</get-function> + <verify-function>glade_gtk_toolbar_verify_size</verify-function> + </property> + </properties> + + <children> + <child> + <type>GtkWidget</type> + <fill-empty-function>empty</fill-empty-function> + </child> + </children> + </glade-widget-class> + + <glade-widget-class name="GtkHandleBox" generic-name="handlebox" title="Handle Box" /> + + <glade-widget-class name="GtkLabel" generic-name="label" title="Label"> + <properties> + <property id="label" default="label"/> + <property id="pattern" default=""/> + </properties> + </glade-widget-class> + + <glade-widget-class name="GtkEntry" generic-name="entry" title="Text Entry"/> + <glade-widget-class name="GtkTextView" generic-name="textview" title="Text View"/> + + <glade-widget-class name="GtkButton" generic-name="button" title="Button"> + <properties> + + <property id="stock" name="Stock Button" default="glade-none"> + <spec>glade_gtk_stock_spec</spec> + <set-function>glade_gtk_button_set_stock</set-function> + </property> + + <property id="response-id" name="Response ID" default="0" common="False"> + <spec>glade_gtk_standard_int_spec</spec> + <tooltip>The response ID of this button in a dialog (it's NOT useful if this button is not in a GtkDialog)</tooltip> + <set-function>ignore</set-function> + <get-function>ignore</get-function> + </property> + + <property id="label" default="button"/> + + </properties> + + <children> + <child> + <type>GtkWidget</type> + <fill-empty-function>empty</fill-empty-function> + </child> + </children> + </glade-widget-class> + + <glade-widget-class name="GtkToggleButton" generic-name="togglebutton" title="Toggle Button"> + <properties> + <property id="label" default="toggle button"/> + </properties> + </glade-widget-class> + + <glade-widget-class name="GtkCheckButton" generic-name="checkbutton" title="Check Button"> + <properties> + <property id="label" default="check button"/> + <property id="draw-indicator" default="True"/> + </properties> + </glade-widget-class> + + <glade-widget-class name="GtkSpinButton" generic-name="spinbutton" title="Spin Button"/> + + <glade-widget-class name="GtkRadioButton" generic-name="radiobutton" title="Radio Button"> + <properties> + <property id="label" default="radio button"/> + <property id="draw-indicator" default="True"/> + <property id="group" name="Group" default="True"> + <spec>glade_gtk_standard_string_spec</spec> + <set-function>glade_gtk_radio_button_set_group</set-function> + <get-function>glade_gtk_radio_button_get_group</get-function> + </property> + </properties> + </glade-widget-class> + + <glade-widget-class name="GtkTreeView" generic-name="treeview" title="Tree View"> + <post-create-function>glade_gtk_tree_view_post_create</post-create-function> + </glade-widget-class> + + <glade-widget-class name="GtkCombo" generic-name="combo" title="Combo Box"/> + + <glade-widget-class name="GtkOptionMenu" generic-name="optionmenu" title="Option Menu"/> + + <glade-widget-class name="GtkProgressBar" generic-name="progressbar" title="Progress Bar"/> + + <glade-widget-class name="GtkImage" generic-name="image" title="Image"> + <properties> + <property id="icon-name" translatable="False"/> + <property id="file" translatable="False"/> + <property id="stock" translatable="False"/> + </properties> + </glade-widget-class> + + <glade-widget-class name="GtkDialog" generic-name="dialog" title="Dialog Box"> + <post-create-function>glade_gtk_dialog_post_create</post-create-function> + <get-internal-child-function>glade_gtk_dialog_get_internal_child</get-internal-child-function> + <child-property-applies-function>glade_gtk_dialog_child_property_applies</child-property-applies-function> + + <properties> + <property id="modal"> + <set-function>ignore</set-function> + </property> + <property id="default-width" default="0" optional="True" optional-default="False"/> + <property id="default-height" default="0" optional="True" optional-default="False"/> + </properties> + + <children> + <child> + <type>GtkWidget</type> + <fill-empty-function>glade_gtk_dialog_fill_empty</fill-empty-function> + + <!-- That's supported, and IMO is the right way to handle --> + <!-- response-id (and it works), but it's not backwards compatible --> + <!-- with response-id being a property as in glade-2. So by now we --> + <!-- will just add a fake response-id property to buttons --> + <!-- + <properties> + <property id="response-id" name="Response ID" default="0" common="False"> + <spec>glade_gtk_standard_int_spec</spec> + <tooltip>The response ID of this button in the dialog</tooltip> + <set-function>ignore</set-function> + <get-function>ignore</get-function> + </property> + </properties> + --> + </child> + </children> + </glade-widget-class> + + <glade-widget-class name="GtkHBox" generic-name="hbox" title="Horizontal Box"/> + <glade-widget-class name="GtkVBox" generic-name="vbox" title="Vertical Box"/> + <glade-widget-class name="GtkTable" generic-name="table" title="Table"> + <properties> + <property id="n-rows" default="3" query="TRUE"> + <parameters> + <parameter key="Min" value="1"/> + <parameter key="Max" value="10000"/> + <parameter key="StepIncrement" value="1"/> + <parameter key="PageIncrement" value="10"/> + <parameter key="ClimbRate" value="1"/> + </parameters> + <set-function>glade_gtk_table_set_n_rows</set-function> + <verify-function>glade_gtk_table_verify_n_rows</verify-function> + </property> + <property id="n-columns" default="3" query="TRUE"> + <parameters> + <parameter key="Min" value="1"/> + <parameter key="Max" value="10000"/> + <parameter key="StepIncrement" value="1"/> + <parameter key="PageIncrement" value="10"/> + <parameter key="ClimbRate" value="1"/> + </parameters> + <set-function>glade_gtk_table_set_n_columns</set-function> + <verify-function>glade_gtk_table_verify_n_columns</verify-function> + </property> + </properties> + + <children> + <child> + <type>GtkWidget</type> + <fill-empty-function>empty</fill-empty-function> + </child> + </children> + </glade-widget-class> + + <glade-widget-class name="GtkHPaned" generic-name="hpaned" title="Horizontal Panes"/> + + <glade-widget-class name="GtkVPaned" generic-name="vpaned" title="Vertical Panes"/> + + <glade-widget-class name="GtkNotebook" generic-name="notebook" title="Notebook"> + <properties> + <property id="pages" name="Number of pages" default="3" query="TRUE"> + <spec>glade_gtk_standard_int_spec</spec> + <tooltip>The number of pages in the notebook</tooltip> + <parameters> + <parameter key="Min" value="1"/> + <parameter key="Max" value="100"/> + <parameter key="StepIncrement" value="1"/> + <parameter key="PageIncrement" value="1"/> + <parameter key="ClimbRate" value="1"/> + </parameters> + <set-function>glade_gtk_notebook_set_n_pages</set-function> + <get-function>glade_gtk_notebook_get_n_pages</get-function> + <verify-function>glade_gtk_notebook_verify_n_pages</verify-function> + </property> + </properties> + + <children> + <child> + <type>GtkWidget</type> + <replace-child-function>glade_gtk_notebook_replace_child</replace-child-function> + <fill-empty-function>empty</fill-empty-function> + <properties> + <property id="tab-label" name="Tab Label Text" > + <spec>glade_gtk_standard_string_spec</spec> + <tooltip>The tab label text of this page widget</tooltip> + <set-function>glade_gtk_notebook_set_tab_label_text</set-function> + <get-function>glade_gtk_notebook_get_tab_label_text</get-function> + </property> + </properties> + </child> + </children> + </glade-widget-class> + + <glade-widget-class name="GtkFrame" generic-name="frame" title="Frame"> + <properties> + <property id="label" default="Frame"/> + </properties> + </glade-widget-class> + + <!-- Gtk+ Additional --> + <glade-widget-class name="GtkHScale" generic-name="hscale" title="Horizontal Scale"/> + + <glade-widget-class name="GtkVScale" generic-name="vscale" title="Vertical Scale"/> + + <glade-widget-class name="GtkCalendar" generic-name="calendar" title="Calendar"/> + + <glade-widget-class name="GtkMenu" generic-name="menu" title="Popup Menu"/> + + <glade-widget-class name="GtkHScrollbar" generic-name="hscrollbar" title="Horizontal Scrollbar"/> + + <glade-widget-class name="GtkVScrollbar" generic-name="vscrollbar" title="Vertical Scrollbar"/> + + <glade-widget-class name="GtkHButtonBox" generic-name="hbuttonbox" title="Horizontal Button Box"/> + + <glade-widget-class name="GtkVButtonBox" generic-name="vbuttonbox" title="Vertical Button Box"/> + + <glade-widget-class name="GtkHSeparator" generic-name="hseparator" title="Horizontal Separator"/> + + <glade-widget-class name="GtkVSeparator" generic-name="vseparator" title="Vertical Separator"/> + + <glade-widget-class name="GtkStatusbar" generic-name="statusbar" title="Status Bar"> + <properties> + <property id="size" disabled="TRUE" /> + <property id="has-resize-grip" name="Has Resize Grip" default="TRUE"> + <type>Boolean</type> + <tooltip>Set if the statusbar has a resize grip or not</tooltip> + <set-function>glade_gtk_statusbar_set_has_resize_grip</set-function> + <get-function>glade_gtk_statusbar_get_has_resize_grip</get-function> + </property> + </properties> + + <children> + <child> + <type>GtkWidget</type> + <fill-empty-function>empty</fill-empty-function> + </child> + </children> + </glade-widget-class> + + <glade-widget-class name="GtkArrow" generic-name="arrow" title="Arrow"/> + <glade-widget-class name="GtkLayout" generic-name="layout" title="Layout"/> + + <glade-widget-class name="GtkFixed" generic-name="fixed" title="Fixed"> + <post-create-function>glade_gtk_fixed_post_create</post-create-function> + + <children> + <child> + <type>GtkWidget</type> + <fill-empty-function>empty</fill-empty-function> + </child> + </children> + </glade-widget-class> + + <glade-widget-class name="GtkDrawingArea" generic-name="drawingarea" title="Drawing Area"/> + + <glade-widget-class name="GtkViewport" generic-name="viewport" title="Viewport"/> + + <glade-widget-class name="GtkScrolledWindow" generic-name="scrolledwindow" title="Scrolled Window"/> + + <!-- NOT AVAILABLES ON WIN32 + <glade-widget-class name="GtkPlug" generic-name="plug" title="Plug"/> + <glade-widget-class name="GtkSocket" generic-name="socket" title="Socket"/> + --> + + <!-- Gtk+ Dialogs --> + <glade-widget-class name="GtkColorSelectionDialog" generic-name="colorselectiondialog" title="Color Selection Dialog"/> + + <glade-widget-class name="GtkFileChooserDialog" generic-name="filechooserdialog" title="File Chooser Dialog"/> + + <glade-widget-class name="GtkFontSelectionDialog" generic-name="fontselectiondialog" title="Font Selection Dialog"/> + + <glade-widget-class name="GtkInputDialog" generic-name="inputdialog" title="Input Dialog"/> + + <glade-widget-class name="GtkMessageDialog" generic-name="messagedialog" title="Message Dialog"> + <post-create-function>glade_gtk_message_dialog_post_create</post-create-function> + + <properties> + + <property id="modal"> + <set-function>ignore</set-function> + </property> + <property id="default-width" default="0" optional="True" optional-default="False"/> + <property id="default-height" default="0" optional="True" optional-default="False"/> + + <property common="True" id="sensitive"/> + <property common="True" id="can-default"/> + <property common="True" id="has-default"/> + <property common="True" id="can-focus"/> + </properties> + </glade-widget-class> + + <!-- Gtk+ Obsolete --> + <glade-widget-class name="GtkRuler"> + <properties> + <property default="10.0" id="upper"/> + <property default="5.0" id="position"/> + <property default="10.0" id="max-size"/> + </properties> + </glade-widget-class> + + <glade-widget-class name="GtkHRuler" generic-name="hruler" title="Horizontal Ruler"/> + + <glade-widget-class name="GtkVRuler" generic-name="vruler" title="Vertical Ruler"/> + + <glade-widget-class name="GtkColorSelection" generic-name="colorselection" title="Color Selection"/> + + <glade-widget-class name="GtkFontSelection" generic-name="fontselection" title="Font Selection"/> + + <glade-widget-class name="GtkCurve" generic-name="curve" title="Curve"/> + + <glade-widget-class name="GtkGammaCurve" generic-name="gammacurve" title="Gamma Curve"/> + + <glade-widget-class name="GtkFileSelection" generic-name="fileselection" title="File Selection"/> + </glade-widget-classes> + + <glade-widget-group name="gtk-base" title="Gtk+ Base"> + <glade-widget-class-ref name="GtkWindow"/> + <glade-widget-class-ref name="GtkMenuBar"/> + <glade-widget-class-ref name="GtkToolbar"/> + <glade-widget-class-ref name="GtkHandleBox"/> + <glade-widget-class-ref name="GtkLabel"/> + <glade-widget-class-ref name="GtkEntry"/> + <glade-widget-class-ref name="GtkTextView"/> + <glade-widget-class-ref name="GtkButton"/> + <glade-widget-class-ref name="GtkToggleButton"/> + <glade-widget-class-ref name="GtkCheckButton"/> + <glade-widget-class-ref name="GtkSpinButton"/> + <glade-widget-class-ref name="GtkRadioButton"/> + <glade-widget-class-ref name="GtkTreeView"/> + <glade-widget-class-ref name="GtkCombo"/> + <glade-widget-class-ref name="GtkOptionMenu"/> + <glade-widget-class-ref name="GtkProgressBar"/> + <glade-widget-class-ref name="GtkImage"/> + <glade-widget-class-ref name="GtkDialog"/> + <glade-widget-class-ref name="GtkHBox"/> + <glade-widget-class-ref name="GtkVBox"/> + <glade-widget-class-ref name="GtkTable"/> + <glade-widget-class-ref name="GtkHPaned"/> + <glade-widget-class-ref name="GtkVPaned"/> + <glade-widget-class-ref name="GtkNotebook"/> + <glade-widget-class-ref name="GtkFrame"/> + </glade-widget-group> + + <glade-widget-group name="gtk-additional" title="Gtk+ Additional"> + <glade-widget-class-ref name="GtkHScale"/> + <glade-widget-class-ref name="GtkVScale"/> + <glade-widget-class-ref name="GtkCalendar"/> + <glade-widget-class-ref name="GtkMenu"/> + <glade-widget-class-ref name="GtkHScrollbar"/> + <glade-widget-class-ref name="GtkVScrollbar"/> + <glade-widget-class-ref name="GtkHButtonBox"/> + <glade-widget-class-ref name="GtkVButtonBox"/> + <glade-widget-class-ref name="GtkHSeparator"/> + <glade-widget-class-ref name="GtkVSeparator"/> + <glade-widget-class-ref name="GtkStatusbar"/> + <glade-widget-class-ref name="GtkArrow"/> + <glade-widget-class-ref name="GtkLayout"/> + <glade-widget-class-ref name="GtkFixed"/> + <glade-widget-class-ref name="GtkDrawingArea"/> + <glade-widget-class-ref name="GtkViewport"/> + <glade-widget-class-ref name="GtkScrolledWindow"/> + </glade-widget-group> + + <glade-widget-group name="gtk-dialogs" title="Gtk+ Standard Dialogs"> + <glade-widget-class-ref name="GtkColorSelectionDialog"/> + <glade-widget-class-ref name="GtkFileChooserDialog"/> + <glade-widget-class-ref name="GtkFontSelectionDialog"/> + <glade-widget-class-ref name="GtkInputDialog"/> + <glade-widget-class-ref name="GtkMessageDialog"/> + </glade-widget-group> + + <glade-widget-group name="gtk-obsolete" title="Gtk+ Obsolete"> + <glade-widget-class-ref name="GtkHRuler"/> + <glade-widget-class-ref name="GtkVRuler"/> + <glade-widget-class-ref name="GtkColorSelection"/> + <glade-widget-class-ref name="GtkFontSelection"/> + <glade-widget-class-ref name="GtkCurve"/> + <glade-widget-class-ref name="GtkGammaCurve"/> + <glade-widget-class-ref name="GtkFileSelection"/> + </glade-widget-group> +</glade-catalog> |