Creating toplevel widget through unified glade-palette interface. Removed

2008-09-16  Pavel Kostyuchenko <ShprotX@gmail.com>

        * gladeui/glade-app.c:
          Creating toplevel widget through unified glade-palette interface.
          Removed error message when pasting non-toplevel widgets without
          a parent.

        * gladeui/glade-command.h: A new function for getting depth of command recursion

        * gladeui/glade-command.c:
          A new function for getting depth of command recursion.
          A return value of glade_command_set_property_execute function is valid
          and is respected by glade_command_set_properties_list.
          indicate success/failure of their execution.
          Glade-command can be unified to null.
          Setting property command is always executed as a group, so if there is
          any recursive command, they will be added to that group.
          Removed parentless widget message level lowered from critical to
          message.
          Widget is treated as toplevel only if it has no parent.
          Removed an assertion from glade_command_create that doesn't allow
          creation of non-GtkWindow parentless widgets

        * gladeui/glade-editor-property.c:
          Object selection dialog will be optionally filled by parentless
          non-GtkWindow widgets only
          Unparenting root widgets before setting another property to them

        * gladeui/glade-inspector.c:
          Popup for clicking even on empty part of widget list

        * gladeui/glade-palette.h:
          A unified function for creating root widgets

        * gladeui/glade-palette.c:
          A unified function for creating root widgets
          A new button for creating root widgets

        * gladeui/glade-placeholder.[ch]:
          glade_placeholder_get_project has been made public for using in
          glade-popup

        * gladeui/glade-popup.c:
          A new function glade_popup_simple_pop for creating a context menu on
          an empty space of glade-inspector
          New context menu items for adding widgets

        * gladeui/glade-popup.h:
          A new function glade_popup_simple_pop for creating a context menu on
          an empty space of glade-inspector

        * gladeui/glade-project.c:
          Unifying command even if there's redo items.
          Unifying atomic commands only.
          Unifying to null

        * gladeui/glade-property-class.[ch]:
          A new field for making properties that points to parentless widgets

        * gladeui/glade-property.h:
          Added a return value to glade_property_set* functions to indicate
          success/failure that is used in glade-command

        * gladeui/glade-property.c:
          Ignoring parentless_widget properties while duplicating properties.
          Additional check while adding/removing property reference
          Added a return value to glade_property_set* functions to indicate
          success/failure that is used in glade-command.
          Determining that property is changed using glade-proproperty method
          instead of direct comparing GValue.
          Loading properties through glade-widget-adaptor interface instead of
          getting them directly.
          remove_object method now unsets referencing property instead of
          setting it.
          Removed dummy duplicated setting of property while unsetting
          referencing property.

        * gladeui/glade-property.h:
          Added a return value to glade_property_set* functions to indicate
          success/failure that is used in glade-command.

        * gladeui/glade-widget.c:
          Removed setting widget properties to template/default values while
          building a new object, because they will be set later in constructor.
          Reloading properties after duplicating a widget.
          A new function for removing parent reference, that was made by setting
          parentless_widget property to the widget.
          Saving and loading parentless_widget properties while rebuilding,
          because they cannot be duplicated.
          Corrected destroying of an old widget while rebuilding. Seems like
          it's not fully correct still.

        * gladeui/glade-widget.h:
          A new function for removing parent reference, that was made by setting
          parentless_widget property to the widget.

        * gladeui/glade-xml-utils.h:
          A new tag "parentless-widget" as a property attribute

        * plugins/gtk+/glade-gtk.c, plugins/gtk+/gtk+.xml.in:
          Removed an old hack for "image" property of GtkMessageDialog.
          A new implementation of "image" property using parentless_widget
          kind of property.
          Added an ability of working with parentless widgets using
          "remove parent" and "add parent" items of context menu


svn path=/trunk/; revision=1908
This commit is contained in:
Pavel Kostyuchenko 2008-09-16 18:25:52 +00:00 committed by Tristan Van Berkom
parent 70e6510afb
commit 7a250eda93
22 changed files with 771 additions and 171 deletions

106
ChangeLog
View File

@ -1,3 +1,109 @@
2008-09-16 Pavel Kostyuchenko <ShprotX@gmail.com>
* gladeui/glade-app.c:
Creating toplevel widget through unified glade-palette interface.
Removed error message when pasting non-toplevel widgets without
a parent.
* gladeui/glade-command.h: A new function for getting depth of command recursion
* gladeui/glade-command.c:
A new function for getting depth of command recursion.
A return value of glade_command_set_property_execute function is valid
and is respected by glade_command_set_properties_list.
indicate success/failure of their execution.
Glade-command can be unified to null.
Setting property command is always executed as a group, so if there is
any recursive command, they will be added to that group.
Removed parentless widget message level lowered from critical to
message.
Widget is treated as toplevel only if it has no parent.
Removed an assertion from glade_command_create that doesn't allow
creation of non-GtkWindow parentless widgets
* gladeui/glade-editor-property.c:
Object selection dialog will be optionally filled by parentless
non-GtkWindow widgets only
Unparenting root widgets before setting another property to them
* gladeui/glade-inspector.c:
Popup for clicking even on empty part of widget list
* gladeui/glade-palette.h:
A unified function for creating root widgets
* gladeui/glade-palette.c:
A unified function for creating root widgets
A new button for creating root widgets
* gladeui/glade-placeholder.[ch]:
glade_placeholder_get_project has been made public for using in
glade-popup
* gladeui/glade-popup.c:
A new function glade_popup_simple_pop for creating a context menu on
an empty space of glade-inspector
New context menu items for adding widgets
* gladeui/glade-popup.h:
A new function glade_popup_simple_pop for creating a context menu on
an empty space of glade-inspector
* gladeui/glade-project.c:
Unifying command even if there's redo items.
Unifying atomic commands only.
Unifying to null
* gladeui/glade-property-class.[ch]:
A new field for making properties that points to parentless widgets
* gladeui/glade-property.h:
Added a return value to glade_property_set* functions to indicate
success/failure that is used in glade-command
* gladeui/glade-property.c:
Ignoring parentless_widget properties while duplicating properties.
Additional check while adding/removing property reference
Added a return value to glade_property_set* functions to indicate
success/failure that is used in glade-command.
Determining that property is changed using glade-proproperty method
instead of direct comparing GValue.
Loading properties through glade-widget-adaptor interface instead of
getting them directly.
remove_object method now unsets referencing property instead of
setting it.
Removed dummy duplicated setting of property while unsetting
referencing property.
* gladeui/glade-property.h:
Added a return value to glade_property_set* functions to indicate
success/failure that is used in glade-command.
* gladeui/glade-widget.c:
Removed setting widget properties to template/default values while
building a new object, because they will be set later in constructor.
Reloading properties after duplicating a widget.
A new function for removing parent reference, that was made by setting
parentless_widget property to the widget.
Saving and loading parentless_widget properties while rebuilding,
because they cannot be duplicated.
Corrected destroying of an old widget while rebuilding. Seems like
it's not fully correct still.
* gladeui/glade-widget.h:
A new function for removing parent reference, that was made by setting
parentless_widget property to the widget.
* gladeui/glade-xml-utils.h:
A new tag "parentless-widget" as a property attribute
* plugins/gtk+/glade-gtk.c, plugins/gtk+/gtk+.xml.in:
Removed an old hack for "image" property of GtkMessageDialog.
A new implementation of "image" property using parentless_widget
kind of property.
Added an ability of working with parentless widgets using
"remove parent" and "add parent" items of context menu
2008-09-16 Tristan Van Berkom <tvb@gnome.org>
* gladeui/glade-design-layout.c: Fixed calculation to get deepest

View File

@ -300,7 +300,7 @@ on_palette_button_clicked (GladePalette *palette, GladeApp *app)
/* class may be NULL if the selector was pressed */
if (adaptor && GWA_IS_TOPLEVEL (adaptor))
{
widget = glade_command_create (adaptor, NULL, NULL, app->priv->active_project);
widget = glade_palette_create_root_widget (palette, adaptor);
/* if this is a top level widget set the accel group */
if (widget && app->priv->accel_group && GTK_IS_WINDOW (widget->object))
@ -308,8 +308,6 @@ on_palette_button_clicked (GladePalette *palette, GladeApp *app)
gtk_window_add_accel_group (GTK_WINDOW (widget->object),
app->priv->accel_group);
}
glade_palette_deselect_current_item (palette, FALSE);
}
}
@ -1296,18 +1294,6 @@ glade_app_command_paste (GladePlaceholder *placeholder)
if (glade_widget_placeholder_relation (parent, widget))
placeholder_relations++;
}
/* Check if there is no parent and at least on of the pasted
* widgets is not a toplevel
*/
else if (!GWA_IS_TOPLEVEL (widget->adaptor) && !parent)
{
glade_util_ui_message (glade_app_get_window (),
GLADE_UI_INFO, NULL,
_("Unable to paste widget %s without a parent"),
widget->name);
return;
}
}
g_assert (widget);

View File

@ -293,6 +293,12 @@ glade_command_pop_group (void)
G_GNUC_PRETTY_FUNCTION);
}
gint
glade_command_get_group_depth (void)
{
return gc_group_depth;
}
static void
glade_command_check_group (GladeCommand *cmd)
{
@ -343,6 +349,8 @@ glade_command_set_property_execute (GladeCommand *cmd)
{
GladeCommandSetProperty* me = (GladeCommandSetProperty*) cmd;
GList *l;
gboolean success;
gboolean retval = FALSE;
g_return_val_if_fail (me != NULL, FALSE);
@ -395,9 +403,10 @@ glade_command_set_property_execute (GladeCommand *cmd)
}
}
glade_property_set_value (sdata->property, &new_value);
success = glade_property_set_value (sdata->property, &new_value);
retval = retval || success;
if (!me->set_once)
if (!me->set_once && success)
{
/* If some verify functions didnt pass on
* the first go.. we need to record the actual
@ -419,7 +428,7 @@ glade_command_set_property_execute (GladeCommand *cmd)
me->set_once = TRUE;
me->undo = !me->undo;
return TRUE;
return retval;
}
static void
@ -458,6 +467,27 @@ glade_command_set_property_unifies (GladeCommand *this_cmd, GladeCommand *other_
GCSetPropData *pdata1, *pdata2;
GList *list, *l;
if (!other_cmd)
{
if (GLADE_IS_COMMAND_SET_PROPERTY (this_cmd))
{
cmd1 = (GladeCommandSetProperty*) this_cmd;
for (list = cmd1->sdata; list; list = list->next)
{
pdata1 = list->data;
if (glade_property_class_compare (pdata1->property->klass,
pdata1->old_value,
pdata1->new_value))
return FALSE;
}
return TRUE;
}
return FALSE;
}
if (GLADE_IS_COMMAND_SET_PROPERTY (this_cmd) &&
GLADE_IS_COMMAND_SET_PROPERTY (other_cmd))
{
@ -579,6 +609,7 @@ glade_command_set_properties_list (GladeProject *project, GList *props)
GladeCommand *cmd;
GCSetPropData *sdata;
GList *list;
gboolean success;
g_return_if_fail (GLADE_IS_PROJECT (project));
g_return_if_fail (props);
@ -594,12 +625,17 @@ glade_command_set_properties_list (GladeProject *project, GList *props)
}
me->sdata = props;
cmd->description = glade_command_set_property_description (me);
cmd->description = NULL;
glade_command_push_group (glade_command_set_property_description (me));
glade_command_check_group (GLADE_COMMAND (me));
/* Push onto undo stack only if it executes successfully. */
if (glade_command_set_property_execute (GLADE_COMMAND (me)))
success = glade_command_set_property_execute (GLADE_COMMAND (me));
glade_command_pop_group ();
if (success)
glade_project_push_undo (GLADE_PROJECT (project),
GLADE_COMMAND (me));
else
@ -932,7 +968,7 @@ glade_command_add (GList *widgets,
else if (GTK_IS_WINDOW (widget->object) == FALSE)
cdata->parent = parent;
if (cdata->parent == NULL && GTK_IS_WINDOW (widget->object) == FALSE)
g_critical ("Parentless non GtkWindow widget in Add");
g_message ("Parentless non GtkWindow widget in Add");
/* Placeholder */
if (placeholder != NULL && g_list_length (widgets) == 1)
@ -1237,7 +1273,7 @@ glade_command_add_execute (GladeCommandAddRemove *me)
/* Toplevels get pasted to the active project */
if (me->from_clipboard &&
GTK_WIDGET_TOPLEVEL (cdata->widget->object))
cdata->widget->parent == NULL)
glade_project_add_object
(active_project, cdata->project,
cdata->widget->object);
@ -1560,8 +1596,6 @@ glade_command_create(GladeWidgetAdaptor *adaptor, GladeWidget *parent, GladePlac
g_return_val_if_fail (GLADE_IS_WIDGET_ADAPTOR (adaptor), NULL);
g_return_val_if_fail (GLADE_IS_PROJECT (project), NULL);
if (GWA_IS_TOPLEVEL(adaptor) == FALSE)
g_return_val_if_fail (GLADE_IS_WIDGET(parent), NULL);
/* attempt to create the widget -- widget may be null, e.g. the user clicked cancel on a query */
widget = glade_widget_adaptor_create_widget(adaptor, TRUE, "parent", parent, "project", project, NULL);

View File

@ -72,6 +72,8 @@ void glade_command_push_group (const gchar *fmt,
void glade_command_pop_group (void);
gint glade_command_get_group_depth (void);
gboolean glade_command_execute (GladeCommand *command);

View File

@ -2345,7 +2345,8 @@ static void
glade_eprop_object_populate_view_real (GladeEditorProperty *eprop,
GtkTreeStore *model,
GList *widgets,
GtkTreeIter *parent_iter)
GtkTreeIter *parent_iter,
gboolean recurse)
{
GList *children, *list;
GtkTreeIter iter;
@ -2360,7 +2361,7 @@ glade_eprop_object_populate_view_real (GladeEditorProperty *eprop,
if (GLADE_IS_PARAM_SPEC_OBJECTS (eprop->klass->pspec))
{
has_decendant = glade_widget_has_decendant
has_decendant = recurse && glade_widget_has_decendant
(widget,
glade_param_spec_objects_get_type
(GLADE_PARAM_SPEC_OBJECTS(eprop->klass->pspec)));
@ -2377,14 +2378,17 @@ glade_eprop_object_populate_view_real (GladeEditorProperty *eprop,
}
else
{
has_decendant = glade_widget_has_decendant
has_decendant = recurse && glade_widget_has_decendant
(widget, eprop->klass->pspec->value_type);
good_type = g_type_is_a (widget->adaptor->type,
eprop->klass->pspec->value_type);
}
if (eprop->klass->parentless_widget)
good_type = good_type && !GWA_IS_TOPLEVEL (widget->adaptor);
if (good_type || has_decendant)
{
gtk_tree_store_append (model, &iter, parent_iter);
@ -2412,7 +2416,7 @@ glade_eprop_object_populate_view_real (GladeEditorProperty *eprop,
GtkTreeIter *copy = NULL;
copy = gtk_tree_iter_copy (&iter);
glade_eprop_object_populate_view_real (eprop, model, children, copy);
glade_eprop_object_populate_view_real (eprop, model, children, copy, recurse);
gtk_tree_iter_free (copy);
g_list_free (children);
@ -2441,7 +2445,7 @@ glade_eprop_object_populate_view (GladeEditorProperty *eprop,
}
/* add the widgets and recurse */
glade_eprop_object_populate_view_real (eprop, model, toplevels, NULL);
glade_eprop_object_populate_view_real (eprop, model, toplevels, NULL, !eprop->klass->parentless_widget);
g_list_free (toplevels);
}
@ -2698,7 +2702,38 @@ glade_eprop_object_show_dialog (GtkWidget *dialog_button,
GValue *value = glade_property_class_make_gvalue_from_string
(eprop->klass, selected->name, project);
glade_editor_property_commit (eprop, value);
/* Unparent the widget so we can reuse it for this property */
if (eprop->klass->parentless_widget)
{
GObject *new_object, *old_object = NULL;
GladeWidget *new_widget;
GladeProperty *old_ref;
if (!G_IS_PARAM_SPEC_OBJECT (eprop->klass->pspec))
g_warning ("Parentless widget property should be of object type");
else
{
glade_property_get (eprop->property, &old_object);
new_object = g_value_get_object (value);
new_widget = glade_widget_get_from_gobject (new_object);
if (new_object && old_object != new_object &&
(old_ref = glade_widget_get_parentless_widget_ref (new_widget)))
{
gchar *desc = g_strdup_printf (_("Setting %s of %s to %s"),
eprop->property->klass->name,
eprop->property->widget->name,
new_widget->name);
glade_command_push_group (desc);
glade_command_set_property (old_ref, NULL);
glade_editor_property_commit (eprop, value);
glade_command_pop_group ();
g_free (desc);
}
}
}
else
glade_editor_property_commit (eprop, value);
g_value_unset (value);
g_free (value);

View File

@ -521,27 +521,31 @@ button_press_cb (GtkWidget *widget,
GtkTreePath *path = NULL;
gboolean handled = FALSE;
if (event->window == gtk_tree_view_get_bin_window (view) &&
gtk_tree_view_get_path_at_pos (view, (gint) event->x, (gint) event->y,
if (event->window == gtk_tree_view_get_bin_window (view))
{
if (gtk_tree_view_get_path_at_pos (view, (gint) event->x, (gint) event->y,
&path, NULL,
NULL, NULL) && path != NULL)
{
GtkTreeIter iter;
GladeWidget *widget = NULL;
if (gtk_tree_model_get_iter (GTK_TREE_MODEL (inspector->priv->model),
&iter, path))
{
/* now we can obtain the widget from the iter.
*/
gtk_tree_model_get (GTK_TREE_MODEL (inspector->priv->model), &iter,
WIDGET_COLUMN, &widget, -1);
if (widget != NULL && event->button == 3)
GtkTreeIter iter;
GladeWidget *widget = NULL;
if (gtk_tree_model_get_iter (GTK_TREE_MODEL (inspector->priv->model),
&iter, path))
{
glade_popup_widget_pop (widget, event, FALSE);
handled = TRUE;
/* now we can obtain the widget from the iter.
*/
gtk_tree_model_get (GTK_TREE_MODEL (inspector->priv->model), &iter,
WIDGET_COLUMN, &widget, -1);
if (widget != NULL && event->button == 3)
{
glade_popup_widget_pop (widget, event, FALSE);
handled = TRUE;
}
gtk_tree_path_free (path);
}
gtk_tree_path_free (path);
}
else
glade_popup_simple_pop (event);
}
return handled;
}

View File

@ -62,6 +62,7 @@ struct _GladePalettePrivate
GtkWidget *selector_hbox;
GtkWidget *selector_button;
GtkWidget *create_root_button;
GtkWidget *tray; /* Where all the item groups are contained */
@ -391,17 +392,42 @@ glade_palette_class_init (GladePaletteClass *klass)
g_type_class_add_private (object_class, sizeof (GladePalettePrivate));
}
GladeWidget *
glade_palette_create_root_widget (GladePalette *palette, GladeWidgetAdaptor *adaptor)
{
GladeWidget *widget;
widget = glade_command_create (adaptor, NULL, NULL, glade_app_get_project ());
glade_palette_deselect_current_item (palette, FALSE);
return widget;
}
static void
glade_palette_on_button_toggled (GtkWidget *button, GladePalette *palette)
{
GladePalettePrivate *priv;
GdkModifierType mask;
GladeWidgetAdaptor *adaptor;
gboolean is_root_active;
g_return_if_fail (GLADE_IS_PALETTE (palette));
g_return_if_fail (GTK_IS_TOGGLE_BUTTON (button));
priv = GLADE_PALETTE_GET_PRIVATE (palette);
is_root_active = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (priv->create_root_button));
if (button == priv->create_root_button && priv->current_item && is_root_active)
{
adaptor = glade_palette_get_current_item (palette);
glade_palette_create_root_widget (palette, adaptor);
return;
}
if (!GLADE_IS_PALETTE_ITEM (button))
return;
/* if we are toggling currently active item into non-active state */
if (priv->current_item == GLADE_PALETTE_ITEM (button))
{
@ -427,6 +453,14 @@ glade_palette_on_button_toggled (GtkWidget *button, GladePalette *palette)
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (priv->current_item), FALSE);
priv->current_item = GLADE_PALETTE_ITEM (button);
if (is_root_active)
{
adaptor = glade_palette_item_get_adaptor (GLADE_PALETTE_ITEM (button));
glade_palette_create_root_widget (palette, adaptor);
return;
}
g_object_notify (G_OBJECT (palette), "current-item");
glade_app_set_pointer_mode (GLADE_POINTER_ADD_WIDGET);
@ -586,6 +620,24 @@ glade_palette_create_selector_button (GladePalette *palette)
return selector;
}
static GtkWidget*
glade_palette_create_create_root_button (GladePalette *palette)
{
GtkWidget *create_root_button;
create_root_button = gtk_toggle_button_new ();
gtk_container_set_border_width (GTK_CONTAINER (create_root_button), 0);
gtk_button_set_use_stock (GTK_BUTTON (create_root_button), TRUE);
gtk_button_set_label (GTK_BUTTON (create_root_button), "gtk-add");
g_signal_connect (G_OBJECT (create_root_button), "toggled",
G_CALLBACK (glade_palette_on_button_toggled),
palette);
return create_root_button;
}
static void
glade_palette_init (GladePalette *palette)
{
@ -604,12 +656,16 @@ glade_palette_init (GladePalette *palette)
/* create selector button */
priv->selector_button = glade_palette_create_selector_button (palette);
priv->selector_hbox = gtk_hbox_new (FALSE, 0);
priv->create_root_button = glade_palette_create_create_root_button (palette);
gtk_box_pack_start (GTK_BOX (priv->selector_hbox), priv->selector_button, FALSE, FALSE, 0);
gtk_box_pack_start (GTK_BOX (priv->selector_hbox), priv->create_root_button, FALSE, FALSE, 0);
gtk_box_pack_start (GTK_BOX (palette), priv->selector_hbox, FALSE, FALSE, 0);
gtk_widget_show (priv->selector_button);
gtk_widget_show (priv->create_root_button);
gtk_widget_show (priv->selector_hbox);
gtk_widget_set_tooltip_text (priv->selector_button, _("Widget selector"));
gtk_widget_set_tooltip_text (priv->selector_button, _("Widget selector"));
gtk_widget_set_tooltip_text (priv->create_root_button, _("Create root widget"));
/* create size group */
priv->size_group = gtk_size_group_new (GTK_SIZE_GROUP_HORIZONTAL);
@ -703,8 +759,9 @@ glade_palette_deselect_current_item (GladePalette *palette, gboolean sticky_awar
if (palette->priv->current_item)
{
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (palette->priv->current_item), FALSE);
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (palette->priv->selector_button), TRUE);
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (palette->priv->selector_button), TRUE);
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (palette->priv->create_root_button), FALSE);
palette->priv->current_item = NULL;
g_object_notify (G_OBJECT (palette), "current-item");

View File

@ -94,6 +94,9 @@ gboolean glade_palette_get_show_selector_button (GladePalette *palet
void glade_palette_refresh (GladePalette *palette);
GladeWidget *glade_palette_create_root_widget (GladePalette *palette,
GladeWidgetAdaptor *adaptor);
G_END_DECLS
#endif /* __GLADE_PALETTE_H__ */

View File

@ -259,7 +259,7 @@ glade_placeholder_send_configure (GladePlaceholder *placeholder)
gdk_event_free (event);
}
static GladeProject*
GladeProject*
glade_placeholder_get_project (GladePlaceholder *placeholder)
{
GladeWidget *parent;

View File

@ -25,6 +25,7 @@
#define __GLADE_PLACEHOLDER_H__
#include <gladeui/glade-widget.h>
#include <gladeui/glade-project.h>
#include <gtk/gtk.h>
G_BEGIN_DECLS
@ -58,6 +59,8 @@ GType glade_placeholder_get_type (void) G_GNUC_CONST;
GtkWidget *glade_placeholder_new (void);
GladeProject* glade_placeholder_get_project (GladePlaceholder *placeholder);
GladeWidget *glade_placeholder_get_parent (GladePlaceholder *placeholder);
G_END_DECLS

View File

@ -47,6 +47,64 @@ glade_popup_select_cb (GtkMenuItem *item, GladeWidget *widget)
(glade_widget_get_object (widget), TRUE);
}
static GladePlaceholder *
find_placeholder (GObject *object)
{
GtkContainer *container;
GladePlaceholder *retval = NULL;
GtkWidget *child;
GList *c, *l;
if (!GTK_IS_CONTAINER (object))
return NULL;
container = GTK_CONTAINER (object);
for (c = l = glade_util_container_get_all_children (container);
l;
l = g_list_next (l))
{
child = l->data;
if (GLADE_IS_PLACEHOLDER (child))
{
retval = GLADE_PLACEHOLDER (child);
break;
}
}
g_list_free (c);
return retval;
}
static void
glade_popup_placeholder_add_cb (GtkMenuItem *item, GladePlaceholder *placeholder)
{
GladeWidgetAdaptor *adaptor;
adaptor = glade_palette_get_current_item (glade_app_get_palette ());
g_return_if_fail (adaptor != NULL);
glade_command_create (adaptor, glade_placeholder_get_parent (placeholder),
placeholder, glade_placeholder_get_project (placeholder));
glade_palette_deselect_current_item (glade_app_get_palette(), TRUE);
}
static void
glade_popup_root_add_cb (GtkMenuItem *item, gpointer *user_data)
{
GladeWidgetAdaptor *adaptor;
GladePalette *palette;
palette = glade_app_get_palette ();
adaptor = glade_palette_get_current_item (palette);
g_return_if_fail (adaptor != NULL);
glade_palette_create_root_widget (palette, adaptor);
}
static void
glade_popup_cut_cb (GtkMenuItem *item, GladeWidget *widget)
{
@ -325,8 +383,35 @@ glade_popup_create_menu (GladeWidget *widget,
{
GtkWidget *popup_menu;
gboolean sensitive;
GladePlaceholder *tmp_placeholder;
sensitive = glade_palette_get_current_item (glade_app_get_palette ()) != NULL;
if (!sensitive && !widget)
return NULL;
popup_menu = gtk_menu_new ();
if (sensitive)
{
tmp_placeholder = placeholder;
if (!tmp_placeholder && widget)
tmp_placeholder = find_placeholder (glade_widget_get_object (widget));
glade_popup_append_item (popup_menu, NULL, _("_Add widget here"), tmp_placeholder != NULL,
glade_popup_placeholder_add_cb, tmp_placeholder);
glade_popup_append_item (popup_menu, NULL, _("Add widget as _root"), TRUE,
glade_popup_root_add_cb, NULL);
}
if (!widget)
return popup_menu;
if (sensitive)
{
GtkWidget *separator = gtk_menu_item_new ();
gtk_menu_shell_append (GTK_MENU_SHELL (popup_menu), separator);
gtk_widget_show (separator);
}
glade_popup_append_item (popup_menu, NULL, _("_Select"), TRUE,
glade_popup_select_cb, widget);
@ -418,7 +503,7 @@ glade_popup_widget_pop (GladeWidget *widget,
gint button;
gint event_time;
g_return_if_fail (GLADE_IS_WIDGET (widget));
g_return_if_fail (GLADE_IS_WIDGET (widget) || widget == NULL);
popup_menu = glade_popup_create_menu (widget, NULL, packing);
@ -492,3 +577,29 @@ glade_popup_clipboard_pop (GladeWidget *widget,
gtk_menu_popup (GTK_MENU (popup_menu), NULL, NULL,
NULL, NULL, button, event_time);
}
void
glade_popup_simple_pop (GdkEventButton *event)
{
GtkWidget *popup_menu;
gint button;
gint event_time;
popup_menu = glade_popup_create_menu (NULL, NULL, FALSE);
if (!popup_menu)
return;
if (event)
{
button = event->button;
event_time = event->time;
}
else
{
button = 0;
event_time = gtk_get_current_event_time ();
}
gtk_menu_popup (GTK_MENU (popup_menu), NULL, NULL,
NULL, NULL, button, event_time);
}

View File

@ -19,6 +19,9 @@ gint glade_popup_action_populate_menu (GtkWidget *menu,
GladeWidgetAction *action,
gboolean packing);
void
glade_popup_simple_pop (GdkEventButton *event);
G_END_DECLS
#endif /* __GLADE_POPUP_H__ */

View File

@ -387,43 +387,29 @@ glade_project_next_redo_item_impl (GladeProject *project)
return l->next ? GLADE_COMMAND (l->next->data) : NULL;
}
static GList *
glade_project_free_undo_item (GladeProject *project, GList *item)
{
g_assert (item->data);
if (item == project->priv->first_modification)
project->priv->first_modification_is_na = TRUE;
g_object_unref (G_OBJECT (item->data));
return g_list_next (item);
}
static void
glade_project_push_undo_impl (GladeProject *project, GladeCommand *cmd)
{
GladeProjectPrivate *priv = project->priv;
GList *tmp_redo_item;
/* If there are no "redo" items, and the last "undo" item unifies with
us, then we collapse the two items in one and we're done */
if (priv->prev_redo_item != NULL && priv->prev_redo_item->next == NULL)
{
GladeCommand *cmd1 = priv->prev_redo_item->data;
if (glade_command_unifies (cmd1, cmd))
{
glade_command_collapse (cmd1, cmd);
g_object_unref (cmd);
g_signal_emit (G_OBJECT (project),
glade_project_signals [CHANGED],
0, cmd1, TRUE);
return;
}
}
/* We should now free all the "redo" items */
tmp_redo_item = g_list_next (priv->prev_redo_item);
while (tmp_redo_item)
{
g_assert (tmp_redo_item->data);
if (tmp_redo_item == priv->first_modification)
priv->first_modification_is_na = TRUE;
g_object_unref (G_OBJECT (tmp_redo_item->data));
tmp_redo_item = g_list_next (tmp_redo_item);
}
tmp_redo_item = glade_project_free_undo_item (project, tmp_redo_item);
if (priv->prev_redo_item)
{
@ -436,6 +422,40 @@ glade_project_push_undo_impl (GladeProject *project, GladeCommand *cmd)
priv->undo_stack = NULL;
}
/* Try to unify only if group depth is 0 */
if (glade_command_get_group_depth() == 0 &&
priv->prev_redo_item != NULL)
{
GladeCommand *cmd1 = priv->prev_redo_item->data;
gboolean is_atomic = FALSE;
/* Cannot unify with a part of a command group.
* Unify atomic commands only
*/
if (cmd1->group_id == 0 || cmd->group_id == 0 ||
cmd->group_id != cmd1->group_id)
is_atomic = TRUE;
if (is_atomic && glade_command_unifies (cmd1, cmd))
{
glade_command_collapse (cmd1, cmd);
g_object_unref (cmd);
if (glade_command_unifies (cmd1, NULL))
{
tmp_redo_item = priv->prev_redo_item;
glade_project_walk_back (project);
glade_project_free_undo_item (project, tmp_redo_item);
priv->undo_stack = g_list_delete_link (priv->undo_stack, tmp_redo_item);
}
g_signal_emit (G_OBJECT (project),
glade_project_signals [CHANGED],
0, NULL, TRUE);
return;
}
}
/* and then push the new undo item */
priv->undo_stack = g_list_append (priv->undo_stack, cmd);

View File

@ -1497,6 +1497,7 @@ glade_property_class_update_from_node (GladeXmlNode *node,
klass->weight = glade_xml_get_property_double (node, GLADE_TAG_WEIGHT, klass->weight);
klass->transfer_on_paste = glade_xml_get_property_boolean (node, GLADE_TAG_TRANSFER_ON_PASTE, klass->transfer_on_paste);
klass->save_always = glade_xml_get_property_boolean (node, GLADE_TAG_SAVE_ALWAYS, klass->save_always);
klass->parentless_widget = glade_xml_get_property_boolean (node, GLADE_TAG_PARENTLESS_WIDGET, klass->parentless_widget);
/* Special case pixbuf here.

View File

@ -159,7 +159,10 @@ struct _GladePropertyClass
* will be used to lookup the theme by the
* implementing widget
*/
gboolean parentless_widget; /* True if this property should point to a parentless widget
* in the project
*/
};

View File

@ -97,7 +97,16 @@ glade_property_dup_impl (GladeProperty *template_prop, GladeWidget *widget)
property->value = g_new0 (GValue, 1);
g_value_init (property->value, template_prop->value->g_type);
g_value_copy (template_prop->value, property->value);
/* Cannot duplicate parentless_widget property */
if (template_prop->klass->parentless_widget)
{
if (!G_IS_PARAM_SPEC_OBJECT (template_prop->klass->pspec))
g_warning ("Parentless widget property should be of object type");
g_value_set_object (property->value, NULL);
}
else
g_value_copy (template_prop->value, property->value);
/* Need value in place here ... */
glade_property_set_enabled (property, template_prop->enabled);
@ -142,13 +151,15 @@ glade_property_update_prop_refs (GladeProperty *property,
{
old_object = list->data;
gold = glade_widget_get_from_gobject (old_object);
glade_widget_remove_prop_ref (gold, property);
if (gold != NULL)
glade_widget_remove_prop_ref (gold, property);
}
for (list = added; list; list = list->next)
{
new_object = list->data;
gnew = glade_widget_get_from_gobject (new_object);
glade_widget_add_prop_ref (gnew, property);
if (gnew != NULL)
glade_widget_add_prop_ref (gnew, property);
}
g_list_free (removed);
@ -161,12 +172,14 @@ glade_property_update_prop_refs (GladeProperty *property,
if ((old_object = g_value_get_object (old_value)) != NULL)
{
gold = glade_widget_get_from_gobject (old_object);
g_return_if_fail (gold != NULL);
glade_widget_remove_prop_ref (gold, property);
}
if ((new_object = g_value_get_object (new_value)) != NULL)
{
gnew = glade_widget_get_from_gobject (new_object);
g_return_if_fail (gnew != NULL);
glade_widget_add_prop_ref (gnew, property);
}
}
@ -227,7 +240,7 @@ glade_property_fix_state (GladeProperty *property)
}
static void
static gboolean
glade_property_set_value_impl (GladeProperty *property, const GValue *value)
{
GladeProject *project = property->widget ?
@ -251,7 +264,7 @@ glade_property_set_value_impl (GladeProperty *property, const GValue *value)
{
g_warning ("Trying to assign an incompatible value to property %s\n",
property->klass->id);
return;
return FALSE;
}
/* Check if the backend doesnt give us permission to
@ -260,12 +273,13 @@ glade_property_set_value_impl (GladeProperty *property, const GValue *value)
if (glade_property_superuser () == FALSE && property->widget &&
project && glade_project_is_loading (project) == FALSE &&
glade_property_verify (property, value) == FALSE)
return;
{
return FALSE;
}
/* save "changed" state.
*/
changed = g_param_values_cmp (property->klass->pspec,
property->value, value) != 0;
changed = !glade_property_equals_value (property, value);
/* Add/Remove references from widget ref stacks here
@ -299,6 +313,8 @@ glade_property_set_value_impl (GladeProperty *property, const GValue *value)
}
g_value_unset (&old_value);
return TRUE;
}
static void
@ -374,7 +390,7 @@ glade_property_load_impl (GladeProperty *property)
oclass = G_OBJECT_GET_CLASS (object);
if (g_object_class_find_property (oclass, property->klass->id))
g_object_get_property (object, property->klass->id, property->value);
glade_widget_object_get_property (property->widget, property->klass->id, property->value);
}
/*******************************************************************************
@ -798,12 +814,12 @@ glade_property_equals (GladeProperty *property, ...)
*
* Sets the property's value
*/
void
gboolean
glade_property_set_value (GladeProperty *property, const GValue *value)
{
g_return_if_fail (GLADE_IS_PROPERTY (property));
g_return_if_fail (value != NULL);
GLADE_PROPERTY_GET_KLASS (property)->set_value (property, value);
g_return_val_if_fail (GLADE_IS_PROPERTY (property), FALSE);
g_return_val_if_fail (value != NULL, FALSE);
return GLADE_PROPERTY_GET_KLASS (property)->set_value (property, value);
}
/**
@ -813,19 +829,22 @@ glade_property_set_value (GladeProperty *property, const GValue *value)
*
* Sets the property's value
*/
void
gboolean
glade_property_set_va_list (GladeProperty *property, va_list vl)
{
GValue *value;
gboolean success;
g_return_if_fail (GLADE_IS_PROPERTY (property));
g_return_val_if_fail (GLADE_IS_PROPERTY (property), FALSE);
value = glade_property_class_make_gvalue_from_vl (property->klass, vl);
GLADE_PROPERTY_GET_KLASS (property)->set_value (property, value);
success = GLADE_PROPERTY_GET_KLASS (property)->set_value (property, value);
g_value_unset (value);
g_free (value);
return success;
}
/**
@ -835,16 +854,19 @@ glade_property_set_va_list (GladeProperty *property, va_list vl)
*
* Sets the property's value (in a convenient way)
*/
void
gboolean
glade_property_set (GladeProperty *property, ...)
{
va_list vl;
gboolean success;
g_return_if_fail (GLADE_IS_PROPERTY (property));
g_return_val_if_fail (GLADE_IS_PROPERTY (property), FALSE);
va_start (vl, property);
glade_property_set_va_list (property, vl);
success = glade_property_set_va_list (property, vl);
va_end (vl);
return success;
}
/**
@ -1286,14 +1308,8 @@ glade_property_remove_object (GladeProperty *property,
}
else
{
glade_property_set (property, object);
glade_property_set (property, NULL);
}
glade_property_class_get_from_gvalue (property->klass,
property->value,
&list);
glade_property_set (property, list);
}
/* Parameters for translatable properties. */

View File

@ -91,7 +91,7 @@ struct _GladePropertyKlass
/* Class methods */
GladeProperty * (* dup) (GladeProperty *, GladeWidget *);
gboolean (* equals_value) (GladeProperty *, const GValue *);
void (* set_value) (GladeProperty *, const GValue *);
gboolean (* set_value) (GladeProperty *, const GValue *);
void (* get_value) (GladeProperty *, GValue *);
void (* get_default) (GladeProperty *, GValue *);
void (* sync) (GladeProperty *);
@ -127,13 +127,13 @@ gboolean glade_property_equals_value (GladeProperty
gboolean glade_property_equals (GladeProperty *property,
...);
void glade_property_set_value (GladeProperty *property,
gboolean glade_property_set_value (GladeProperty *property,
const GValue *value);
void glade_property_set_va_list (GladeProperty *property,
gboolean glade_property_set_va_list (GladeProperty *property,
va_list vl);
void glade_property_set (GladeProperty *property,
gboolean glade_property_set (GladeProperty *property,
...);
void glade_property_get_value (GladeProperty *property,

View File

@ -508,7 +508,7 @@ glade_widget_build_object (GladeWidgetAdaptor *adaptor,
{
GParameter *params;
GObject *object;
guint n_params, i;
guint n_params;
if (reason == GLADE_CREATE_LOAD)
return g_object_new (adaptor->type, NULL);
@ -524,18 +524,6 @@ glade_widget_build_object (GladeWidgetAdaptor *adaptor,
free_params (params, n_params);
if (widget)
params = glade_widget_template_params (widget, FALSE, &n_params);
else
params = glade_widget_adaptor_default_params (adaptor, FALSE, &n_params);
for (i = 0; i < n_params; i++)
{
g_object_set_property (object, params[i].name, &(params[i].value));
}
free_params (params, n_params);
return object;
}
@ -1301,9 +1289,10 @@ glade_widget_dup_internal (GladeWidget *parent,
{
GladeGetInternalFunc get_internal;
GladeWidget *gwidget = NULL, *internal_parent;
GList *list, *children;
GList *children;
GtkWidget *placeholder;
gchar *child_type;
GList *l;
g_return_val_if_fail (template_widget != NULL && GLADE_IS_WIDGET(template_widget), NULL);
g_return_val_if_fail (parent == NULL || GLADE_IS_WIDGET (parent), NULL);
@ -1351,6 +1340,8 @@ glade_widget_dup_internal (GladeWidget *parent,
glade_widget_adaptor_get_children (template_widget->adaptor,
template_widget->object)) != NULL)
{
GList *list;
for (list = children; list && list->data; list = list->next)
{
GObject *child = G_OBJECT (list->data);
@ -1417,6 +1408,10 @@ glade_widget_dup_internal (GladeWidget *parent,
*/
glade_widget_sync_custom_props (gwidget);
/* Some properties may not be synced so we reload them */
for (l = gwidget->properties; l; l = l->next)
glade_property_load (GLADE_PROPERTY (l->data));
/* Special case GtkWindow here and ensure the pasted window
* has the same size as the 'Cut' one.
*/
@ -1938,6 +1933,25 @@ glade_widget_remove_prop_ref (GladeWidget *widget, GladeProperty *property)
widget->prop_refs = g_list_remove (widget->prop_refs, property);
}
GladeProperty *
glade_widget_get_parentless_widget_ref (GladeWidget *widget)
{
GList *l;
GladeProperty *property;
g_return_val_if_fail (GLADE_IS_WIDGET (widget), NULL);
for (l = widget->prop_refs; l && l->data; l = l->next)
{
property = GLADE_PROPERTY (l->data);
if (property->klass->parentless_widget)
/* For now only one property can point to the widget */
return property;
}
return NULL;
}
/**
* glade_widget_project_notify:
* @widget: A #GladeWidget
@ -2146,6 +2160,12 @@ glade_widget_dup (GladeWidget *template_widget,
return widget;
}
typedef struct
{
gchar *name;
GValue value;
} PropertyData;
/**
* glade_widget_rebuild:
* @gwidget: a #GladeWidget
@ -2162,6 +2182,8 @@ glade_widget_rebuild (GladeWidget *gwidget)
GladeWidgetAdaptor *adaptor;
GList *children;
gboolean reselect = FALSE, inproject;
GList *npw_properties = NULL;
GList *l;
g_return_if_fail (GLADE_IS_WIDGET (gwidget));
@ -2190,6 +2212,28 @@ glade_widget_rebuild (GladeWidget *gwidget)
/* Extract and keep the child hierarchies aside... */
children = glade_widget_extract_children (gwidget);
/* parentless_widget properties should be unset before transfering */
for (l = gwidget->properties; l; l = l->next)
{
GladeProperty *property = GLADE_PROPERTY (l->data);
if (property->klass->parentless_widget)
{
PropertyData *prop_data;
if (!G_IS_PARAM_SPEC_OBJECT (property->klass->pspec))
g_warning ("Parentless widget property should be of object type");
prop_data = g_new0 (PropertyData, 1);
prop_data->name = g_strdup (property->klass->id);
g_value_init (&prop_data->value, property->value->g_type);
g_value_copy (property->value, &prop_data->value);
npw_properties = g_list_prepend (npw_properties,
prop_data);
glade_property_set (property, NULL);
}
}
/* Hold a reference to the old widget while we transport properties
* and children from it
*/
@ -2207,6 +2251,12 @@ glade_widget_rebuild (GladeWidget *gwidget)
glade_widget_replace (gwidget->parent,
old_object, new_object);
/* Must call dispose for cases like dialogs and toplevels */
if (g_type_is_a (adaptor->type, GTK_TYPE_OBJECT))
gtk_object_destroy (GTK_OBJECT (old_object));
else
g_object_run_dispose (G_OBJECT (old_object));
/* Reparent any children of the old object to the new object
* (this function will consume and free the child list).
*/
@ -2219,19 +2269,23 @@ glade_widget_rebuild (GladeWidget *gwidget)
*/
glade_widget_sync_custom_props (gwidget);
/* Setting parentless_widget properties back */
for (l = npw_properties; l; l = l->next)
{
PropertyData *prop_data = l->data;
GladeProperty *property = glade_widget_get_property (gwidget, prop_data->name);
glade_property_set_value (property, &prop_data->value);
g_value_unset (&prop_data->value);
g_free (prop_data->name);
g_free (prop_data);
}
npw_properties = NULL;
/* Sync packing.
*/
glade_widget_sync_packing_props (gwidget);
if (g_type_is_a (adaptor->type, GTK_TYPE_WIDGET))
{
/* Must use gtk_widget_destroy here for cases like dialogs and toplevels
* (otherwise I'd prefer g_object_unref() )
*/
gtk_widget_destroy (GTK_WIDGET(old_object));
}
else
g_object_unref (old_object);
/* If the widget was in a project (and maybe the selection), then
* restore that stuff.

View File

@ -269,6 +269,8 @@ void glade_widget_add_prop_ref (GladeWidget *w
void glade_widget_remove_prop_ref (GladeWidget *widget,
GladeProperty *property);
GladeProperty *glade_widget_get_parentless_widget_ref (GladeWidget *widget);
/*******************************************************************************
Functions that deal with properties on the runtime object
*******************************************************************************/

View File

@ -79,6 +79,7 @@ typedef struct _GladeXmlDoc GladeXmlDoc;
#define GLADE_TAG_SIGNALS "signals"
#define GLADE_TAG_SIGNAL "signal"
#define GLADE_TAG_DEFAULT "default"
#define GLADE_TAG_PARENTLESS_WIDGET "parentless-widget"
#define GLADE_TAG_DISABLED "disabled"
#define GLADE_TAG_DEFAULT_PALETTE_STATE "default-palette-state"
#define GLADE_TAG_REPLACE_CHILD_FUNCTION "replace-child-function"

View File

@ -1076,8 +1076,7 @@ widget_parent_changed (GtkWidget *widget,
if (!gwidget)
return;
if (gwidget->parent && !GTK_IS_WINDOW (glade_widget_get_object (gwidget->parent)) &&
gwidget->parent->internal == NULL)
if (gwidget->parent && gwidget->parent->internal == NULL)
glade_widget_set_action_sensitive (gwidget, "remove_parent", TRUE);
else
glade_widget_set_action_sensitive (gwidget, "remove_parent", FALSE);
@ -1171,18 +1170,17 @@ glade_gtk_widget_action_activate (GladeWidgetAdaptor *adaptor,
GList this_widget = { 0, }, that_widget = { 0, };
GtkWidget *parent = GTK_WIDGET (object)->parent;
g_assert (parent);
if (parent)
gparent = glade_widget_get_from_gobject (parent);
else
gparent = NULL;
gparent = glade_widget_get_from_gobject (parent);
if (strcmp (action_path, "remove_parent") == 0)
{
GladeWidget *new_gparent = gparent->parent;
GladeWidget *new_gparent;
/* Since toplevel project objects for now must be GtkWindow,
* we'll just assert this for now (should be an insensitive action).
*/
g_assert (!GTK_IS_WINDOW (parent));
g_return_if_fail (gparent);
new_gparent = gparent->parent;
glade_command_push_group (_("Removing parent of %s"),
gwidget->name);
@ -1234,8 +1232,9 @@ glade_gtk_widget_action_activate (GladeWidgetAdaptor *adaptor,
{
GladeWidgetAdaptor *adaptor = glade_widget_adaptor_get_by_type (new_type);
GList *saved_props, *prop_cmds;
GladeProject *project;
glade_command_push_group (_("Adding parent %s to %s"),
glade_command_push_group (_("Adding parent %s for %s"),
adaptor->title, gwidget->name);
/* Record packing properties */
@ -1244,11 +1243,15 @@ glade_gtk_widget_action_activate (GladeWidgetAdaptor *adaptor,
/* Remove "this" widget */
this_widget.data = gwidget;
glade_command_cut (&this_widget);
if (gparent)
project = glade_widget_get_project (gparent);
else
project = glade_app_get_project ();
/* Create new widget and put it where the placeholder was */
that_widget.data =
glade_command_create (adaptor, gparent, NULL,
glade_widget_get_project (gparent));
project);
/* Remove the alignment that we added in the frame's post_create... */
@ -4859,27 +4862,6 @@ glade_gtk_dialog_get_children (GladeWidgetAdaptor *adaptor,
return list;
}
void
glade_gtk_dialog_set_property (GladeWidgetAdaptor *adaptor,
GObject *object,
const gchar *id,
const GValue *value)
{
if (GTK_IS_MESSAGE_DIALOG (object) && !strcmp (id, "image"))
{
/* Gtk+ 2.10 crashes when you unset the image of
* a message dialog, so we dont ever unset it.
*/
if (g_value_get_object (value))
gtk_message_dialog_set_image (GTK_MESSAGE_DIALOG (object),
GTK_WIDGET (g_value_get_object (value)));
}
else
GWA_GET_CLASS (GTK_TYPE_WINDOW)->set_property (adaptor, object,
id, value);
}
/* ----------------------------- GtkFileChooserWidget ------------------------------ */
void
glade_gtk_file_chooser_widget_post_create (GladeWidgetAdaptor *adaptor,
@ -8052,3 +8034,177 @@ glade_gtk_radio_button_set_property (GladeWidgetAdaptor *adaptor,
property_name,
value);
}
/*--------------------------- GtkMessageDialog ---------------------------------*/
static gboolean
glade_gtk_message_dialog_reset_image (GtkMessageDialog *dialog)
{
gint message_type;
g_object_get (dialog, "message-type", &message_type, NULL);
if (message_type != GTK_MESSAGE_OTHER)
return FALSE;
if (glade_widget_get_from_gobject (dialog->image))
{
gtk_message_dialog_set_image (dialog,
gtk_image_new_from_stock (NULL, GTK_ICON_SIZE_DIALOG));
gtk_widget_show (dialog->image);
return TRUE;
}
else
return FALSE;
}
enum {
MD_IMAGE_ACTION_INVALID,
MD_IMAGE_ACTION_RESET,
MD_IMAGE_ACTION_SET
};
static gint
glade_gtk_message_dialog_image_determine_action (GtkMessageDialog *dialog,
const GValue *value,
GtkWidget **image,
GladeWidget **gimage)
{
*image = g_value_get_object (value);
if (*image == NULL)
if (glade_widget_get_from_gobject (dialog->image))
return MD_IMAGE_ACTION_RESET;
else
return MD_IMAGE_ACTION_INVALID;
else
{
*image = GTK_WIDGET (*image);
if (dialog->image == *image)
return MD_IMAGE_ACTION_INVALID;
if (gtk_widget_get_parent (*image))
return MD_IMAGE_ACTION_INVALID;
*gimage = glade_widget_get_from_gobject (*image);
if (!*gimage)
{
g_warning ("Setting property to an object outside the project");
return MD_IMAGE_ACTION_INVALID;
}
if (glade_widget_get_parent (*gimage) || GTK_IS_WINDOW (*image))
return MD_IMAGE_ACTION_INVALID;
return MD_IMAGE_ACTION_SET;
}
}
void
glade_gtk_message_dialog_set_property (GladeWidgetAdaptor *adaptor,
GObject *object,
const gchar *id,
const GValue *value)
{
GtkMessageDialog *dialog = GTK_MESSAGE_DIALOG (object);
GladeWidget *gwidget = glade_widget_get_from_gobject (object);
g_return_if_fail (gwidget);
if (strcmp (id, "image") == 0)
{
GtkWidget *image = NULL;
GladeWidget *gimage = NULL;
gint rslt;
rslt = glade_gtk_message_dialog_image_determine_action (dialog, value,
&image, &gimage);
switch (rslt)
{
case MD_IMAGE_ACTION_INVALID:
return;
case MD_IMAGE_ACTION_RESET:
glade_gtk_message_dialog_reset_image (dialog);
return;
case MD_IMAGE_ACTION_SET:
break; /* continue setting the property */
}
if (gtk_widget_get_parent (image))
g_critical ("Image should have no parent now");
gtk_message_dialog_set_image (dialog, image);
{
/* syncing "message-type" property */
GladeProperty *property;
property = glade_widget_get_property (gwidget, "message-type");
if (!glade_property_equals (property, GTK_MESSAGE_OTHER))
glade_command_set_property (property, GTK_MESSAGE_OTHER);
}
}
else
{
/* We must reset the image to internal,
* external image would otherwise become internal
*/
if (!strcmp (id, "message-type") &&
g_value_get_enum (value) != GTK_MESSAGE_OTHER)
{
GladeProperty *property;
property = glade_widget_get_property (gwidget, "image");
if (!glade_property_equals (property, NULL))
glade_command_set_property (property, NULL);
}
/* Chain up, even if property us message-type because
* it's not fully handled here
*/
GWA_GET_CLASS (GTK_TYPE_DIALOG)->set_property (adaptor, object,
id, value);
}
}
gboolean
glade_gtk_message_dialog_verify_property (GladeWidgetAdaptor *adaptor,
GObject *object,
const gchar *id,
const GValue *value)
{
if (!strcmp (id, "image"))
{
GtkWidget *image; GladeWidget *gimage;
gboolean retval = MD_IMAGE_ACTION_INVALID !=
glade_gtk_message_dialog_image_determine_action (GTK_MESSAGE_DIALOG (object),
value, &image, &gimage);
return retval;
}
else
if (GWA_GET_CLASS (GTK_TYPE_CONTAINER)->verify_property)
return GWA_GET_CLASS (GTK_TYPE_CONTAINER)->verify_property (adaptor, object,
id, value);
else
return TRUE;
}
void
glade_gtk_message_dialog_get_property (GladeWidgetAdaptor *adaptor,
GObject *object,
const gchar *property_name,
GValue *value)
{
if (!strcmp (property_name, "image"))
{
GtkMessageDialog *dialog = GTK_MESSAGE_DIALOG (object);
if (!glade_widget_get_from_gobject (dialog->image))
g_value_set_object (value, NULL);
else
g_value_set_object (value, dialog->image);
}
else
GWA_GET_CLASS (GTK_TYPE_DIALOG)->get_property (adaptor, object,
property_name, value);
}

View File

@ -1022,7 +1022,6 @@ embedded in another object</_tooltip>
<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>
<get-children-function>glade_gtk_dialog_get_children</get-children-function>
<set-property-function>glade_gtk_dialog_set_property</set-property-function>
<properties>
<property id="default-width" default="320" optional="True" optional-default="False"/>
<property id="default-height" default="260" optional="True" optional-default="False"/>
@ -1489,6 +1488,10 @@ embedded in another object</_tooltip>
</glade-widget-class>
<glade-widget-class name="GtkMessageDialog" generic-name="messagedialog" _title="Message Dialog" default-width="400" default-height="115">
<set-property-function>glade_gtk_message_dialog_set_property</set-property-function>
<get-property-function>glade_gtk_message_dialog_get_property</get-property-function>
<verify-function>glade_gtk_message_dialog_verify_property</verify-function>
<properties>
<property id="default-width" default="400" optional="True" optional-default="False"/>
<property id="default-height" default="115" optional="True" optional-default="False"/>
@ -1498,7 +1501,7 @@ embedded in another object</_tooltip>
<property common="True" id="has-default"/>
<property common="True" id="can-focus"/>
<property id="image" since="2.10"/>
<property id="image" since="2.10" parentless-widget="True"/>
<property id="secondary-text" since="2.10"/>
<property id="secondary-use-markup" since="2.10"/>
<property id="text" since="2.10"/>