diff --git a/ChangeLog b/ChangeLog index c7a2c3e5..33498709 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,13 @@ +2008-10-30 Tristan Van Berkom + + * gladeui/glade-widget.[ch], gladeui/glade-command.[ch]: Added + glade_widget_[un]lock() and glade_command_[un]lock_widget(). + + * plugins/gtk+/glade-gtk.c, plugins/gtk+/gtk+.xml.in, plugins/gtk+/glade-convert.c, + plugins/gtk+/glade-image-item-editor.c: Dual format menu editing support + depending on my gtk+ patch on bug 527672, TODO: still need to add accel-groups + to GtkWindow on the glade side of things. + 2008-10-28 Tristan Van Berkom * plugins/gtk+/gtk+.xml.in, plugins/gtk+/glade-gtk.c: diff --git a/gladeui/glade-app.c b/gladeui/glade-app.c index ef2fa7f4..2283e9c0 100644 --- a/gladeui/glade-app.c +++ b/gladeui/glade-app.c @@ -1126,18 +1126,6 @@ glade_app_command_copy (void) { widget = glade_widget_get_from_gobject (GTK_WIDGET (list->data)); widgets = g_list_prepend (widgets, widget); - - g_assert (widget); - if (widget->internal) - { - glade_util_ui_message - (glade_app_get_window(), - GLADE_UI_WARN, NULL, - _("You cannot copy a widget " - "internal to a composite widget.")); - failed = TRUE; - break; - } } if (failed == FALSE && widgets != NULL) @@ -1179,18 +1167,6 @@ glade_app_command_cut (void) { widget = glade_widget_get_from_gobject (GTK_WIDGET (list->data)); widgets = g_list_prepend (widgets, widget); - - g_assert (widget); - if (widget->internal) - { - glade_util_ui_message - (glade_app_get_window(), - GLADE_UI_WARN, NULL, - _("You cannot cut a widget " - "internal to a composite widget.")); - failed = TRUE; - break; - } } if (failed == FALSE && widgets != NULL) @@ -1349,20 +1325,8 @@ glade_app_command_delete (void) { widget = glade_widget_get_from_gobject (list->data); widgets = g_list_prepend (widgets, widget); - - g_assert (widget); - if (widget->internal) - { - glade_util_ui_message - (glade_app_get_window(), - GLADE_UI_WARN, NULL, - _("You cannot delete a widget " - "internal to a composite widget.")); - failed = TRUE; - break; - } } - + if (failed == FALSE && widgets != NULL) { glade_command_delete (widgets); @@ -1391,21 +1355,10 @@ glade_app_command_delete_clipboard (void) clipboard = glade_app_get_clipboard (); if (clipboard->selection == NULL) + { glade_util_ui_message (glade_app_get_window (), GLADE_UI_INFO, NULL, _("No widget selected on the clipboard")); - - for (list = clipboard->selection; list; list = list->next) - { - gwidget = list->data; - if (gwidget->internal) - { - glade_util_ui_message - (glade_app_get_window(), - GLADE_UI_WARN, NULL, - _("You cannot delete a widget " - "internal to a composite widget.")); - return; - } + return; } glade_command_delete (clipboard->selection); diff --git a/gladeui/glade-command.c b/gladeui/glade-command.c index 744b922c..789c204d 100644 --- a/gladeui/glade-command.c +++ b/gladeui/glade-command.c @@ -1072,6 +1072,23 @@ glade_command_delete_prop_refs (GladeWidget *widget) } } +static void glade_command_remove (GList *widgets); + +static void +glade_command_remove_locked (GladeWidget *widget) +{ + GList list = { 0, }; + GladeWidget *locked; + + while (widget->locked_widgets) + { + locked = widget->locked_widgets->data; + list.data = locked; + + glade_command_unlock_widget (locked); + glade_command_remove (&list); + } +} /** * glade_command_remove: @@ -1106,10 +1123,12 @@ glade_command_remove (GList *widgets) _("You cannot remove a widget internal to a composite widget.")); return; } - if (widget->protection) + if (widget->lock) { glade_util_ui_message (glade_app_get_window(), - GLADE_UI_WARN, NULL, widget->protection); + GLADE_UI_WARN, NULL, + _("%s is locked by %s, edit %s first."), + widget->name, widget->lock->name, widget->lock->name); return; } } @@ -1135,9 +1154,15 @@ glade_command_remove (GList *widgets) /* Undoably unset any object properties that may point to the removed object */ glade_command_delete_prop_refs (widget); + /* Undoably unlock and remove any widgets locked by this widget */ + glade_command_remove_locked (widget); + if (widget->internal) g_critical ("Internal widget in Remove"); + if (widget->lock) + g_critical ("Locked widget in Remove"); + if (cdata->parent != NULL && glade_widget_placeholder_relation (cdata->parent, cdata->widget)) @@ -2545,106 +2570,110 @@ glade_command_set_project_naming_policy (GladeProject *project, typedef struct { GladeCommand parent; GladeWidget *widget; - gchar *warning; - gboolean protecting; -} GladeCommandProtect; + GladeWidget *locked; + gboolean locking; +} GladeCommandLock; -GLADE_MAKE_COMMAND (GladeCommandProtect, glade_command_protect); -#define GLADE_COMMAND_PROTECT_TYPE (glade_command_protect_get_type ()) -#define GLADE_COMMAND_PROTECT(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), GLADE_COMMAND_PROTECT_TYPE, GladeCommandProtect)) -#define GLADE_COMMAND_PROTECT_CLASS(k) (G_TYPE_CHECK_CLASS_CAST ((k), GLADE_COMMAND_PROTECT_TYPE, GladeCommandProtectClass)) -#define GLADE_IS_COMMAND_PROTECT(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), GLADE_COMMAND_PROTECT_TYPE)) -#define GLADE_IS_COMMAND_PROTECT_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), GLADE_COMMAND_PROTECT_TYPE)) +GLADE_MAKE_COMMAND (GladeCommandLock, glade_command_lock); +#define GLADE_COMMAND_LOCK_TYPE (glade_command_lock_get_type ()) +#define GLADE_COMMAND_LOCK(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), GLADE_COMMAND_LOCK_TYPE, GladeCommandLock)) +#define GLADE_COMMAND_LOCK_CLASS(k) (G_TYPE_CHECK_CLASS_CAST ((k), GLADE_COMMAND_LOCK_TYPE, GladeCommandLockClass)) +#define GLADE_IS_COMMAND_LOCK(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), GLADE_COMMAND_LOCK_TYPE)) +#define GLADE_IS_COMMAND_LOCK_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), GLADE_COMMAND_LOCK_TYPE)) static gboolean -glade_command_protect_execute(GladeCommand *cmd) +glade_command_lock_execute(GladeCommand *cmd) { - GladeCommandProtect *me = (GladeCommandProtect *)cmd; + GladeCommandLock *me = (GladeCommandLock *)cmd; /* set the new policy */ - if (me->protecting) - glade_widget_protect (me->widget, me->warning); + if (me->locking) + glade_widget_lock (me->widget, me->locked); else - glade_widget_unprotect (me->widget); + glade_widget_unlock (me->locked); /* swap the current values with the old values to prepare for undo */ - me->protecting = !me->protecting; + me->locking = !me->locking; return TRUE; } static gboolean -glade_command_protect_undo(GladeCommand *cmd) +glade_command_lock_undo(GladeCommand *cmd) { - return glade_command_protect_execute(cmd); + return glade_command_lock_execute(cmd); } static void -glade_command_protect_finalize(GObject *obj) +glade_command_lock_finalize(GObject *obj) { - GladeCommandProtect *me = (GladeCommandProtect *)obj; + GladeCommandLock *me = (GladeCommandLock *)obj; g_object_unref (me->widget); + g_object_unref (me->locked); glade_command_finalize(obj); } static gboolean -glade_command_protect_unifies (GladeCommand *this_cmd, GladeCommand *other_cmd) +glade_command_lock_unifies (GladeCommand *this_cmd, GladeCommand *other_cmd) { -/* GladeCommandProtect *cmd1; */ -/* GladeCommandProtect *cmd2; */ +/* GladeCommandLock *cmd1; */ +/* GladeCommandLock *cmd2; */ /* No point here, this command undoubtedly always runs in groups */ return FALSE; } static void -glade_command_protect_collapse (GladeCommand *this_cmd, GladeCommand *other_cmd) +glade_command_lock_collapse (GladeCommand *this_cmd, GladeCommand *other_cmd) { /* this command is the one that will be used for an undo of the sequence of like commands */ - //GladeCommandProtect *this = GLADE_COMMAND_PROTECT (this_cmd); + //GladeCommandLock *this = GLADE_COMMAND_LOCK (this_cmd); /* the other command contains the values that will be used for a redo */ - //GladeCommandProtect *other = GLADE_COMMAND_PROTECT (other_cmd); + //GladeCommandLock *other = GLADE_COMMAND_LOCK (other_cmd); - g_return_if_fail (GLADE_IS_COMMAND_PROTECT (this_cmd) && GLADE_IS_COMMAND_PROTECT (other_cmd)); + g_return_if_fail (GLADE_IS_COMMAND_LOCK (this_cmd) && GLADE_IS_COMMAND_LOCK (other_cmd)); /* no unify/collapse */ } /** - * glade_command_protect_widget: + * glade_command_lock_widget: * @widget: A #GladeWidget - * @warning: the warning to print when a user tries to delete this widget + * @locked: The #GladeWidget to lock * - * Sets the protection status and @warning on @widget + * Sets @locked to be in a locked up state + * spoken for by @widget, locked widgets cannot + * be removed from the project until unlocked. */ void -glade_command_protect_widget (GladeWidget *widget, - const gchar *warning) +glade_command_lock_widget (GladeWidget *widget, + GladeWidget *locked) { - GladeCommandProtect *me; + GladeCommandLock *me; g_return_if_fail (GLADE_IS_WIDGET (widget)); - g_return_if_fail (widget->protection == NULL); - g_return_if_fail (warning && warning[0]); + g_return_if_fail (GLADE_IS_WIDGET (locked)); + g_return_if_fail (locked->lock == NULL); /* load up the command */ - me = g_object_new(GLADE_COMMAND_PROTECT_TYPE, NULL); + me = g_object_new(GLADE_COMMAND_LOCK_TYPE, NULL); me->widget = g_object_ref (widget); - me->protecting = TRUE; - me->warning = g_strdup (warning); + me->locked = g_object_ref (locked); + me->locking = TRUE; - GLADE_COMMAND(me)->description = g_strdup_printf(_("Protecting %s"), widget->name); + GLADE_COMMAND(me)->description = g_strdup_printf(_("Locking %s by widget %s"), + locked->name, widget->name); glade_command_check_group(GLADE_COMMAND(me)); /* execute the command and push it on the stack if successful * this sets the actual policy */ - if (glade_command_protect_execute(GLADE_COMMAND(me))) + if (glade_command_lock_execute(GLADE_COMMAND(me))) glade_project_push_undo(glade_app_get_project(), GLADE_COMMAND(me)); else g_object_unref(G_OBJECT(me)); @@ -2653,34 +2682,36 @@ glade_command_protect_widget (GladeWidget *widget, /** - * glade_command_unprotect_widget: + * glade_command_unlock_widget: * @widget: A #GladeWidget * - * Unsets the protection status of @widget + * Unlocks @widget so that it can be removed + * from the project again + * */ void -glade_command_unprotect_widget (GladeWidget *widget) +glade_command_unlock_widget (GladeWidget *widget) { - GladeCommandProtect *me; + GladeCommandLock *me; g_return_if_fail (GLADE_IS_WIDGET (widget)); - g_return_if_fail (widget->protection && widget->protection[0]); + g_return_if_fail (GLADE_IS_WIDGET (widget->lock)); /* load up the command */ - me = g_object_new(GLADE_COMMAND_PROTECT_TYPE, NULL); - me->widget = g_object_ref (widget); - me->protecting = FALSE; - me->warning = g_strdup (widget->protection); + me = g_object_new(GLADE_COMMAND_LOCK_TYPE, NULL); + me->widget = g_object_ref (widget->lock); + me->locked = g_object_ref (widget); + me->locking = FALSE; - GLADE_COMMAND(me)->description = g_strdup_printf(_("Unprotecting %s"), widget->name); + GLADE_COMMAND(me)->description = g_strdup_printf(_("Unlocking %s"), widget->name); glade_command_check_group(GLADE_COMMAND(me)); /* execute the command and push it on the stack if successful * this sets the actual policy */ - if (glade_command_protect_execute(GLADE_COMMAND(me))) + if (glade_command_lock_execute(GLADE_COMMAND(me))) glade_project_push_undo(glade_app_get_project(), GLADE_COMMAND(me)); else g_object_unref(G_OBJECT(me)); diff --git a/gladeui/glade-command.h b/gladeui/glade-command.h index 0c9c2216..405589eb 100644 --- a/gladeui/glade-command.h +++ b/gladeui/glade-command.h @@ -116,10 +116,10 @@ void glade_command_set_name (GladeWidget *glade_widget, con /************************ protection ******************************/ -void glade_command_protect_widget (GladeWidget *widget, - const gchar *warning); +void glade_command_lock_widget (GladeWidget *widget, + GladeWidget *lock); -void glade_command_unprotect_widget (GladeWidget *widget); +void glade_command_unlock_widget (GladeWidget *widget); /************************ create/delete ******************************/ diff --git a/gladeui/glade-widget.c b/gladeui/glade-widget.c index d999cba0..a4105e32 100644 --- a/gladeui/glade-widget.c +++ b/gladeui/glade-widget.c @@ -4166,24 +4166,44 @@ glade_widget_set_support_warning (GladeWidget *widget, g_object_notify (G_OBJECT (widget), "support-warning"); } +/** + * glade_widget_lock: + * @widget: A #GladeWidget + * @locked: The #GladeWidget to lock + * + * Sets @locked to be in a locked up state + * spoken for by @widget, locked widgets cannot + * be removed from the project until unlocked. + * + */ void -glade_widget_protect (GladeWidget *widget, - const gchar *warning) +glade_widget_lock (GladeWidget *widget, + GladeWidget *locked) { g_return_if_fail (GLADE_IS_WIDGET (widget)); - g_return_if_fail (warning && warning[0]); - - if (widget->protection) - g_free (widget->protection); - widget->protection = g_strdup (warning); + g_return_if_fail (GLADE_IS_WIDGET (locked)); + g_return_if_fail (locked->lock == NULL); + + locked->lock = widget; + widget->locked_widgets = + g_list_prepend (widget->locked_widgets, locked); } +/** + * glade_widget_unlock: + * @widget: A #GladeWidget + * + * Unlocks @widget so that it can be removed + * from the project again + * + */ void -glade_widget_unprotect (GladeWidget *widget) +glade_widget_unlock (GladeWidget *widget) { g_return_if_fail (GLADE_IS_WIDGET (widget)); + g_return_if_fail (GLADE_IS_WIDGET (widget->lock)); - if (widget->protection) - g_free (widget->protection); - widget->protection = NULL; + widget->lock->locked_widgets = + g_list_remove (widget->lock->locked_widgets, widget); + widget->lock = NULL; } diff --git a/gladeui/glade-widget.h b/gladeui/glade-widget.h index ec53903e..8b256ea1 100644 --- a/gladeui/glade-widget.h +++ b/gladeui/glade-widget.h @@ -41,11 +41,6 @@ struct _GladeWidget * in this widget */ - gchar *protection; /* custom editors are allowed to add protected widgets that - * cannot be deleted by the user in normal ways. - * (this is a message to be displayed in the dialog - * when the user tries to delete it). - */ gchar *internal; /* If the widget is an internal child of * another widget this is the name of the @@ -107,6 +102,11 @@ struct _GladeWidget GList *packing_actions; /* A GladeWidgetAction list, this actions are * related to the container and they are not always present. */ + + GladeWidget *lock; /* The glade widget that has locked this widget down. + */ + GList *locked_widgets; /* A list of widgets this widget has locked down. + */ /* Construct parameters: */ GladeWidget *construct_template; @@ -410,9 +410,9 @@ void glade_widget_pop_superuser (void); void glade_widget_set_support_warning (GladeWidget *widget, const gchar *warning); -void glade_widget_protect (GladeWidget *widget, - const gchar *warning); -void glade_widget_unprotect (GladeWidget *widget); +void glade_widget_lock (GladeWidget *widget, + GladeWidget *locked); +void glade_widget_unlock (GladeWidget *widget); G_END_DECLS diff --git a/plugins/gtk+/glade-convert.c b/plugins/gtk+/glade-convert.c index 9578f46d..7b935bd4 100644 --- a/plugins/gtk+/glade-convert.c +++ b/plugins/gtk+/glade-convert.c @@ -57,6 +57,7 @@ typedef struct { GList *tooltips; GList *combos; GList *toolbuttons; + GList *menus; } ConvertData; /***************************************** @@ -719,6 +720,86 @@ convert_toolbuttons (GladeProject *project, } } +/****************************************** + * GtkImageMenuItem:image,accel-group * + ******************************************/ +static void +convert_menus_finished (GladeProject *project, + ConvertData *data) +{ + GList *l; + GladeWidget *widget, *accel_group = NULL; + GladeProperty *property; + + for (l = data->menus; l; l = l->next) + { + widget = l->data; + property = glade_widget_get_property (widget, "accel-group"); + + if (accel_group == NULL) + accel_group = glade_command_create (glade_widget_adaptor_get_by_type (GTK_TYPE_ACCEL_GROUP), + NULL, NULL, project); + + glade_command_set_property (property, accel_group->object); + + } + g_list_free (data->menus); +} + +static GladeWidget * +get_image_widget (GladeWidget *widget) +{ + GtkWidget *image; + image = gtk_image_menu_item_get_image (GTK_IMAGE_MENU_ITEM (widget->object)); + return image ? glade_widget_get_from_gobject (image) : NULL; +} + +static void +convert_menus (GladeProject *project, + GladeProjectFormat new_format, + ConvertData *data) +{ + GladeWidget *widget; + GladeProperty *property; + const GList *objects; + GladeWidget *gimage; + gboolean use_stock; + + for (objects = glade_project_get_objects (project); objects; objects = objects->next) + { + widget = glade_widget_get_from_gobject (objects->data); + if (!GTK_IS_IMAGE_MENU_ITEM (widget->object)) + continue; + + glade_widget_property_get (widget, "use-stock", &use_stock); + + /* convert images */ + if ((gimage = get_image_widget (widget)) != NULL) + { + GList list = { 0, }; + + list.data = gimage; + + glade_command_unlock_widget (gimage); + glade_command_cut (&list); + + if (new_format == GLADE_PROJECT_FORMAT_GTKBUILDER) + { + property = glade_widget_get_property (widget, "image"); + glade_command_paste (&list, NULL, NULL); + glade_command_set_property (property, gimage->object); + } + else + glade_command_paste (&list, widget, NULL); + + glade_command_lock_widget (widget, gimage); + } + + if (new_format == GLADE_PROJECT_FORMAT_GTKBUILDER && use_stock) + data->menus = g_list_prepend (data->menus, widget); + } + +} /***************************************** * Main entry point * @@ -732,6 +813,7 @@ glade_gtk_project_convert_finished (GladeProject *project, convert_tooltips_finished (project, data); convert_combos_finished (project, data); convert_toolbuttons_finished (project, data); + convert_menus_finished (project, data); /* Once per conversion */ g_signal_handlers_disconnect_by_func (G_OBJECT (project), @@ -751,6 +833,7 @@ glade_gtk_project_convert (GladeProject *project, convert_tooltips (project, new_format, data); convert_combos (project, new_format, data); convert_toolbuttons (project, new_format, data); + convert_menus (project, new_format, data); /* Clean up after the new_format is in effect */ g_signal_connect (G_OBJECT (project), "convert-finished", diff --git a/plugins/gtk+/glade-gtk.c b/plugins/gtk+/glade-gtk.c index 0cb5ed9d..d0d594be 100644 --- a/plugins/gtk+/glade-gtk.c +++ b/plugins/gtk+/glade-gtk.c @@ -4758,6 +4758,8 @@ glade_gtk_window_post_create (GladeWidgetAdaptor *adaptor, /* Chain her up first */ GWA_GET_CLASS (GTK_TYPE_CONTAINER)->post_create (adaptor, object, reason); + + } /* ----------------------------- GtkDialog(s) ------------------------------ */ @@ -5423,6 +5425,23 @@ glade_gtk_menu_constructor (GType type, return ret_obj; } +void +glade_gtk_menu_read_widget (GladeWidgetAdaptor *adaptor, + GladeWidget *widget, + GladeXmlNode *node) +{ + if (!glade_xml_node_verify + (node, GLADE_XML_TAG_WIDGET (glade_project_get_format (widget->project)))) + return; + + /* First chain up and read in all the normal properties.. */ + GWA_GET_CLASS (G_TYPE_OBJECT)->read_widget (adaptor, widget, node); + + if (glade_project_get_format (widget->project) == GLADE_PROJECT_FORMAT_LIBGLADE && + widget->parent && GTK_IS_MENU_ITEM (widget->parent->object)) + g_object_set_data (widget->object, "special-child-type", "submenu"); +} + /* ----------------------------- GtkMenuShell ------------------------------ */ void @@ -5664,7 +5683,7 @@ glade_gtk_menu_shell_change_type (GladeBaseEditor *editor, if (image && (widget = glade_widget_get_from_gobject (image))) { list.data = widget; - glade_command_unprotect_widget (widget); + glade_command_unlock_widget (widget); glade_command_delete (&list); } } @@ -5815,7 +5834,7 @@ glade_gtk_menu_item_constructor (GType type, return ret_obj; } - + void glade_gtk_menu_item_post_create (GladeWidgetAdaptor *adaptor, GObject *object, @@ -5823,9 +5842,7 @@ glade_gtk_menu_item_post_create (GladeWidgetAdaptor *adaptor, { GladeWidget *gitem; - g_return_if_fail (GTK_IS_MENU_ITEM (object)); gitem = glade_widget_get_from_gobject (object); - g_return_if_fail (GLADE_IS_WIDGET (gitem)); if (GTK_IS_SEPARATOR_MENU_ITEM (object)) return; @@ -5919,7 +5936,53 @@ glade_gtk_menu_item_set_property (GladeWidgetAdaptor *adaptor, id, value); } +static gboolean +write_special_child_submenu_item (GladeWidgetAdaptor *adaptor, + GladeWidget *widget, + GladeXmlContext *context, + GladeXmlNode *node, + GladeWriteWidgetFunc write_func) +{ + gchar *special_child_type = NULL; + GObject *child; + + if (glade_project_get_format (widget->project) == GLADE_PROJECT_FORMAT_LIBGLADE) + { + child = widget->object; + if (child) + special_child_type = g_object_get_data (child, "special-child-type"); + } + + if (special_child_type && !strcmp (special_child_type, "submenu")) + { + g_object_set_data (child, "special-child-type", NULL); + write_func (adaptor, widget, context, node); + g_object_set_data (child, "special-child-type", "submenu"); + return TRUE; + } + else + return FALSE; +} + +void +glade_gtk_menu_item_write_child (GladeWidgetAdaptor *adaptor, + GladeWidget *widget, + GladeXmlContext *context, + GladeXmlNode *node) +{ + + if (!write_special_child_submenu_item (adaptor, widget, context, node, + GWA_GET_CLASS(GTK_TYPE_CONTAINER)->write_child)) + /* Chain Up */ + GWA_GET_CLASS + (GTK_TYPE_CONTAINER)->write_child (adaptor, + widget, + context, + node); +} + /* ----------------------------- GtkImageMenuItem ------------------------------ */ + GList * glade_gtk_image_menu_item_get_children (GladeWidgetAdaptor *adaptor, GObject *object) @@ -5932,8 +5995,7 @@ glade_gtk_image_menu_item_get_children (GladeWidgetAdaptor *adaptor, if ((child = gtk_menu_item_get_submenu (GTK_MENU_ITEM (object)))) list = g_list_append (list, child); - if (GTK_IS_IMAGE_MENU_ITEM (object) && - (child = gtk_image_menu_item_get_image (GTK_IMAGE_MENU_ITEM (object)))) + if ((child = gtk_image_menu_item_get_image (GTK_IMAGE_MENU_ITEM (object)))) list = g_list_append (list, child); return list; @@ -6003,18 +6065,19 @@ glade_gtk_image_menu_item_set_label (GObject *object, const GValue *value) image = gtk_image_new_from_stock (g_value_get_string (value), GTK_ICON_SIZE_MENU); gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (object), image); + /* Just for display purposes, real stock menuitems automatically have underline + * property set. */ + gtk_label_set_use_underline (GTK_LABEL (label), TRUE); + /* Get the label string... */ if (text && gtk_stock_lookup (text, &item)) - gtk_label_set_text (GTK_LABEL (label), item.label); + gtk_label_set_label (GTK_LABEL (label), item.label); else - gtk_label_set_text (GTK_LABEL (label), text); + gtk_label_set_label (GTK_LABEL (label), text ? text : ""); - /* Just for display purposes, real stock menuitems dont need the underline property, - * but do have mnemonic label. */ - gtk_label_set_use_underline (GTK_LABEL (label), TRUE); } else - gtk_label_set_text (GTK_LABEL (label), g_value_get_string (value)); + gtk_label_set_label (GTK_LABEL (label), text ? text : ""); /* Update underline incase... */ gtk_label_set_use_underline (GTK_LABEL (label), use_underline); @@ -6048,7 +6111,6 @@ static GladeWidget * glade_gtk_image_menu_item_create_image (GladeWidget *gitem) { GladeWidget *gimage; - gchar *protection; gimage = glade_widget_adaptor_create_widget (glade_widget_adaptor_get_by_type (GTK_TYPE_IMAGE), FALSE, @@ -6059,11 +6121,7 @@ glade_gtk_image_menu_item_create_image (GladeWidget *gitem) gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (gitem->object), GTK_WIDGET (gimage->object)); - protection = g_strdup_printf (_("Cannot delete %s because it is used by %s, " - "try editing %s instead."), - gimage->name, gitem->name, gitem->name); - glade_widget_protect (gimage, protection); - g_free (protection); + glade_widget_lock (gitem, gimage); return gimage; } @@ -6183,6 +6241,18 @@ glade_gtk_image_menu_item_fix_stock_item (GladeWidget *widget) glade_widget_property_set (widget, "label", label); } +static void +glade_gtk_image_menu_item_parse_finished (GladeProject *project, + GladeWidget *widget) +{ + GladeWidget *gimage; + GtkWidget *image = NULL; + glade_widget_property_get (widget, "image", &image); + + if (image && (gimage = glade_widget_get_from_gobject (image))) + glade_widget_lock (widget, gimage); +} + void glade_gtk_image_menu_item_read_widget (GladeWidgetAdaptor *adaptor, GladeWidget *widget, @@ -6207,9 +6277,16 @@ glade_gtk_image_menu_item_read_widget (GladeWidgetAdaptor *adaptor, gchar *label = NULL; glade_property_get (property, &label); + glade_widget_property_set (widget, "use-underline", TRUE); glade_widget_property_set (widget, "stock", label); glade_property_sync (property); } + + /* Run this after the load so that image is resolved. */ + if (glade_project_get_format (widget->project) == GLADE_PROJECT_FORMAT_GTKBUILDER) + g_signal_connect (G_OBJECT (widget->project), "parse-finished", + G_CALLBACK (glade_gtk_image_menu_item_parse_finished), + widget); } @@ -6241,12 +6318,12 @@ glade_gtk_image_menu_item_write_widget (GladeWidgetAdaptor *adaptor, g_object_unref (G_OBJECT (label_prop)); /* Chain up and write all the normal properties ... */ - GWA_GET_CLASS (G_TYPE_OBJECT)->write_widget (adaptor, widget, context, node); + GWA_GET_CLASS (GTK_TYPE_MENU_ITEM)->write_widget (adaptor, widget, context, node); } -/* Read in the internal "image" widgets as normal "protected" widgets... +/* Read in the internal "image" widgets as normal "locked" widgets... */ void glade_gtk_image_menu_item_read_child (GladeWidgetAdaptor *adaptor, @@ -6276,14 +6353,8 @@ glade_gtk_image_menu_item_read_child (GladeWidgetAdaptor *adaptor, { if (GTK_IS_IMAGE (child_widget->object) && internal_name && strcmp (internal_name, "image") == 0) - { - gchar *protection = - g_strdup_printf (_("Cannot delete %s because it is used by %s, " - "try editing %s instead."), - child_widget->name, widget->name, widget->name); - glade_widget_protect (child_widget, protection); - g_free (protection); - } + glade_widget_lock (widget, child_widget); + glade_widget_add_child (widget, child_widget, FALSE); } } @@ -6300,7 +6371,7 @@ glade_gtk_image_menu_item_write_child (GladeWidgetAdaptor *adaptor, if (!GTK_IS_IMAGE (widget->object)) { - GWA_GET_CLASS (G_TYPE_OBJECT)->write_child (adaptor, widget, context, node); + GWA_GET_CLASS (GTK_TYPE_MENU_ITEM)->write_child (adaptor, widget, context, node); return; } diff --git a/plugins/gtk+/glade-image-item-editor.c b/plugins/gtk+/glade-image-item-editor.c index 04796e97..81d3192d 100644 --- a/plugins/gtk+/glade-image-item-editor.c +++ b/plugins/gtk+/glade-image-item-editor.c @@ -204,7 +204,7 @@ stock_toggled (GtkWidget *widget, GladeImageItemEditor *item_editor) { GladeProperty *property; - GladeWidget *image; + GladeWidget *image, *loaded; if (item_editor->loading || !item_editor->loaded_widget) return; @@ -213,24 +213,26 @@ stock_toggled (GtkWidget *widget, return; item_editor->modifying = TRUE; + loaded = item_editor->loaded_widget; - glade_command_push_group (_("Setting %s to use a stock item"), item_editor->loaded_widget->name); + glade_command_push_group (_("Setting %s to use a stock item"), loaded->name); - property = glade_widget_get_property (item_editor->loaded_widget, "label"); + property = glade_widget_get_property (loaded, "label"); glade_command_set_property (property, NULL); - property = glade_widget_get_property (item_editor->loaded_widget, "use-underline"); + property = glade_widget_get_property (loaded, "use-underline"); glade_command_set_property (property, FALSE); /* Delete image... */ - if ((image = get_image_widget (item_editor->loaded_widget)) != NULL) + if ((image = get_image_widget (loaded)) != NULL) { GList list = { 0, }; list.data = image; - glade_command_unprotect_widget (image); + glade_command_unlock_widget (image); glade_command_delete (&list); + glade_project_selection_set (loaded->project, loaded->object, TRUE); } - property = glade_widget_get_property (item_editor->loaded_widget, "use-stock"); + property = glade_widget_get_property (loaded, "use-stock"); glade_command_set_property (property, TRUE); glade_command_pop_group (); @@ -238,8 +240,7 @@ stock_toggled (GtkWidget *widget, item_editor->modifying = FALSE; /* reload buttons and sensitivity and stuff... */ - glade_editable_load (GLADE_EDITABLE (item_editor), - item_editor->loaded_widget); + glade_editable_load (GLADE_EDITABLE (item_editor), item_editor->loaded_widget); } static void @@ -275,15 +276,25 @@ custom_toggled (GtkWidget *widget, { /* item_editor->loaded_widget may be set to NULL after the create_command. */ GladeWidget *loaded = item_editor->loaded_widget; - GladeWidget *image = - glade_command_create (glade_widget_adaptor_get_by_type (GTK_TYPE_IMAGE), - item_editor->loaded_widget, NULL, - glade_widget_get_project (item_editor->loaded_widget)); - gchar *protection = g_strdup_printf (_("Cannot delete %s because it is used by %s, " - "try editing %s instead."), - image->name, loaded->name, loaded->name); - glade_command_protect_widget (image, protection); - g_free (protection); + GladeWidget *image; + + if (glade_project_get_format (loaded->project) == GLADE_PROJECT_FORMAT_LIBGLADE) + image = glade_command_create (glade_widget_adaptor_get_by_type (GTK_TYPE_IMAGE), + item_editor->loaded_widget, NULL, + glade_widget_get_project (loaded)); + else + { + image = glade_command_create (glade_widget_adaptor_get_by_type (GTK_TYPE_IMAGE), + NULL, NULL, glade_widget_get_project (loaded)); + + glade_command_set_property (loaded, "image", image); + } + + /* Make sure nobody deletes this... */ + glade_command_lock_widget (loaded, image); + + /* reload widget by selection ;-) */ + glade_project_selection_set (loaded->project, loaded->object, TRUE); } glade_command_pop_group (); diff --git a/plugins/gtk+/gtk+.xml.in b/plugins/gtk+/gtk+.xml.in index e97b9647..12846b20 100644 --- a/plugins/gtk+/gtk+.xml.in +++ b/plugins/gtk+/gtk+.xml.in @@ -368,6 +368,9 @@ embedded in another object glade_gtk_menu_item_add_child glade_gtk_menu_item_remove_child glade_gtk_menu_item_action_activate + glade_gtk_menu_item_write_child + submenu + @@ -391,6 +394,7 @@ embedded in another object + glade_gtk_image_menu_item_post_create glade_gtk_image_menu_item_read_widget glade_gtk_image_menu_item_write_widget glade_gtk_image_menu_item_read_child @@ -411,7 +415,10 @@ embedded in another object - + + + + glade_gtk_menu_constructor + + glade_gtk_menu_read_widget + empty @@ -1565,6 +1574,8 @@ embedded in another object +