Commit 7a250eda authored by Pavel Kostyuchenko's avatar Pavel Kostyuchenko Committed by Tristan Van Berkom

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
parent 70e6510a
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
......
......@@ -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);
......
......@@ -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);
......
......@@ -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);
......
......@@ -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);
......
......@@ -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;
}
......
......@@ -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");
......
......@@ -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__ */
......
......@@ -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;
......
......@@ -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
......
......@@ -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);
}
......@@ -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__ */
......@@ -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)