Commit 0b47674c authored by Tristan Van Berkom's avatar Tristan Van Berkom

* gladeui/glade-widget-action.[ch], gladeui/glade-widget-adaptor.c, gladeui/glade-widget.[ch],

	gladeui/glade-popup.c, plugins/gtk+/glade-gtk.c, src/glade-window.c:
	- Privatized members of GladeWidgetAction
	- Created glade_widget_action_class_new() and some accessors for better code in
	  the adaptor
	- GWActionClass is now on the slice allocator
	- Added glade_widget_action_set/get_visible()
	- Removed glade_widget_remove[_pack]_action()
	- Plugin makes actions invisible instead of removing them
	- Everything updated for new sealed api
parent 0523a44d
......@@ -18,6 +18,17 @@
* gladeui/glade-placeholder.[ch], gladeui/glade-popup.c:
Privatized GladePlaceholder members.
* gladeui/glade-widget-action.[ch], gladeui/glade-widget-adaptor.c, gladeui/glade-widget.[ch],
gladeui/glade-popup.c, plugins/gtk+/glade-gtk.c, src/glade-window.c:
- Privatized members of GladeWidgetAction
- Created glade_widget_action_class_new() and some accessors for better code in
the adaptor
- GWActionClass is now on the slice allocator
- Added glade_widget_action_set/get_visible()
- Removed glade_widget_remove[_pack]_action()
- Plugin makes actions invisible instead of removing them
- Everything updated for new sealed api
2011-01-04 Johannes Schmid <jhs@gnome.org>
* data/gladeui-2.0.pc.in: Fix include paths and library name
......
......@@ -307,32 +307,37 @@ glade_popup_action_populate_menu_real (GtkWidget * menu,
for (list = actions; list; list = g_list_next (list))
{
GladeWidgetAction *a = list->data;
GtkWidget *submenu = NULL;
GladeWidgetAction *action = list->data;
GWActionClass *aclass = glade_widget_action_get_class (action);
GList *children = glade_widget_action_get_children (action);
GtkWidget *submenu = NULL;
if (a->actions)
if (!glade_widget_action_get_visible (action))
continue;
if (children)
{
submenu = gtk_menu_new ();
n += glade_popup_action_populate_menu_real (submenu,
gwidget,
a->actions,
children,
callback, data);
}
else
submenu = glade_widget_adaptor_action_submenu (glade_widget_get_adaptor (gwidget),
glade_widget_get_object (gwidget),
a->klass->path);
aclass->path);
item = glade_popup_append_item (menu,
a->klass->stock,
a->klass->label, NULL, TRUE,
(a->actions) ? NULL : callback,
(a->actions) ? NULL : a->klass->path);
aclass->stock,
aclass->label, NULL, TRUE,
(children) ? NULL : callback,
(children) ? NULL : aclass->path);
g_object_set_data (G_OBJECT (item), "gwa-data", data);
gtk_widget_set_sensitive (item, a->sensitive);
gtk_widget_set_sensitive (item, glade_widget_action_get_sensitive (action));
if (submenu)
gtk_menu_item_set_submenu (GTK_MENU_ITEM (item), submenu);
......@@ -364,21 +369,27 @@ glade_popup_action_populate_menu (GtkWidget * menu,
g_return_val_if_fail (GTK_IS_MENU (menu), 0);
g_return_val_if_fail (GLADE_IS_WIDGET (widget), 0);
g_return_val_if_fail (action == NULL || GLADE_IS_WIDGET_ACTION (action), 0);
if (action)
{
g_return_val_if_fail (GLADE_IS_WIDGET_ACTION (action), 0);
if (glade_widget_get_action (widget, action->klass->path))
GWActionClass *aclass = glade_widget_action_get_class (action);
GList *children = glade_widget_action_get_children (action);
if (glade_widget_get_action (widget, aclass->path) &&
glade_widget_action_get_visible (action))
return glade_popup_action_populate_menu_real (menu,
widget,
action->actions,
children,
G_CALLBACK
(glade_popup_menuitem_activated),
widget);
if (glade_widget_get_pack_action (widget, action->klass->path))
if (glade_widget_get_pack_action (widget, aclass->path) &&
glade_widget_action_get_visible (action))
return glade_popup_action_populate_menu_real (menu,
glade_widget_get_parent
(widget), action->actions,
(widget), children,
G_CALLBACK
(glade_popup_menuitem_packing_activated),
widget);
......@@ -401,6 +412,7 @@ glade_popup_action_populate_menu (GtkWidget * menu,
gtk_menu_shell_append (GTK_MENU_SHELL (menu), separator);
gtk_widget_show (separator);
}
n += glade_popup_action_populate_menu_real
(menu, glade_widget_get_parent (widget),
glade_widget_get_pack_actions (widget),
......
......@@ -38,7 +38,16 @@ enum
PROP_0,
PROP_CLASS,
PROP_SENSITIVE
PROP_SENSITIVE,
PROP_VISIBLE
};
struct _GladeWidgetActionPrivate
{
GWActionClass *klass; /* The action class */
GList *actions; /* List of actions */
guint sensitive : 1; /* If this action is sensitive or not */
guint visible : 1; /* If this action is visible or not */
};
G_DEFINE_TYPE (GladeWidgetAction, glade_widget_action, G_TYPE_OBJECT);
......@@ -46,8 +55,13 @@ G_DEFINE_TYPE (GladeWidgetAction, glade_widget_action, G_TYPE_OBJECT);
static void
glade_widget_action_init (GladeWidgetAction * object)
{
object->sensitive = TRUE;
object->actions = NULL;
object->priv = G_TYPE_INSTANCE_GET_PRIVATE (object,
GLADE_TYPE_WIDGET_ACTION,
GladeWidgetActionPrivate);
object->priv->sensitive = TRUE;
object->priv->visible = TRUE;
object->priv->actions = NULL;
}
static void
......@@ -55,10 +69,10 @@ glade_widget_action_finalize (GObject * object)
{
GladeWidgetAction *action = GLADE_WIDGET_ACTION (object);
if (action->actions)
if (action->priv->actions)
{
g_list_foreach (action->actions, (GFunc) g_object_unref, NULL);
g_list_free (action->actions);
g_list_foreach (action->priv->actions, (GFunc) g_object_unref, NULL);
g_list_free (action->priv->actions);
}
G_OBJECT_CLASS (glade_widget_action_parent_class)->finalize (object);
......@@ -78,24 +92,24 @@ glade_widget_action_constructor (GType type,
action = GLADE_WIDGET_ACTION (object);
if (action->klass == NULL)
if (action->priv->klass == NULL)
{
g_warning ("GladeWidgetAction constructed without class property");
return object;
}
for (l = action->klass->actions; l; l = g_list_next (l))
for (l = action->priv->klass->actions; l; l = g_list_next (l))
{
GWActionClass *action_class = l->data;
GObject *obj = g_object_new (GLADE_TYPE_WIDGET_ACTION,
"class", action_class,
NULL);
action->actions = g_list_prepend (action->actions,
GLADE_WIDGET_ACTION (obj));
action->priv->actions = g_list_prepend (action->priv->actions,
GLADE_WIDGET_ACTION (obj));
}
action->actions = g_list_reverse (action->actions);
action->priv->actions = g_list_reverse (action->priv->actions);
return object;
}
......@@ -111,11 +125,14 @@ glade_widget_action_set_property (GObject * object, guint prop_id,
switch (prop_id)
{
case PROP_CLASS:
action->klass = g_value_get_pointer (value);
action->priv->klass = g_value_get_pointer (value);
break;
case PROP_SENSITIVE:
glade_widget_action_set_sensitive (action, g_value_get_boolean (value));
break;
case PROP_VISIBLE:
glade_widget_action_set_visible (action, g_value_get_boolean (value));
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
......@@ -133,10 +150,13 @@ glade_widget_action_get_property (GObject * object, guint prop_id,
switch (prop_id)
{
case PROP_CLASS:
g_value_set_pointer (value, action->klass);
g_value_set_pointer (value, action->priv->klass);
break;
case PROP_SENSITIVE:
g_value_set_boolean (value, action->sensitive);
g_value_set_boolean (value, action->priv->sensitive);
break;
case PROP_VISIBLE:
g_value_set_boolean (value, action->priv->visible);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
......@@ -169,31 +189,111 @@ glade_widget_action_class_init (GladeWidgetActionClass * klass)
PROP_SENSITIVE,
g_param_spec_boolean ("sensitive",
_("Sensitive"),
_
("Whether this action is sensitive"),
_("Whether this action is sensitive"),
TRUE,
G_PARAM_READWRITE));
g_object_class_install_property (object_class,
PROP_VISIBLE,
g_param_spec_boolean ("visible",
_("Visible"),
_("Whether this action is visible"),
TRUE,
G_PARAM_READWRITE));
g_type_class_add_private (klass, sizeof (GladeWidgetActionPrivate));
}
/**
* glade_widegt_action_class_free:
* @action: a GWActionClass
* glade_widget_action_set_sensitive:
* @action: a #GladeWidgetAction
* @sensitive:
*
* Set whether or not this action is sensitive.
*
* Frees a GWActionClass.
*/
void
glade_widget_action_class_free (GWActionClass * action)
glade_widget_action_set_sensitive (GladeWidgetAction * action,
gboolean sensitive)
{
if (action->actions)
g_list_foreach (action->actions, (GFunc) glade_widget_action_class_free,
NULL);
g_return_if_fail (GLADE_IS_WIDGET_ACTION (action));
/*Dont free id since it points to path */
g_free (action->path);
g_free (action->label);
g_free (action->stock);
g_free (action);
action->priv->sensitive = sensitive;
g_object_notify (G_OBJECT (action), "sensitive");
}
gboolean
glade_widget_action_get_sensitive (GladeWidgetAction *action)
{
g_return_val_if_fail (GLADE_IS_WIDGET_ACTION (action), FALSE);
return action->priv->sensitive;
}
void
glade_widget_action_set_visible (GladeWidgetAction *action,
gboolean visible)
{
g_return_if_fail (GLADE_IS_WIDGET_ACTION (action));
action->priv->visible = visible;
g_object_notify (G_OBJECT (action), "visible");
}
gboolean
glade_widget_action_get_visible (GladeWidgetAction *action)
{
g_return_val_if_fail (GLADE_IS_WIDGET_ACTION (action), FALSE);
return action->priv->visible;
}
GList *
glade_widget_action_get_children (GladeWidgetAction *action)
{
g_return_val_if_fail (GLADE_IS_WIDGET_ACTION (action), NULL);
return action->priv->actions;
}
GWActionClass *
glade_widget_action_get_class (GladeWidgetAction *action)
{
g_return_val_if_fail (GLADE_IS_WIDGET_ACTION (action), NULL);
return action->priv->klass;
}
/***************************************************************
* GWActionClass *
***************************************************************/
static const gchar *
gwa_action_path_get_id (const gchar * action_path)
{
const gchar *id;
if ((id = g_strrstr (action_path, "/")) && id[1] != '\0')
return &id[1];
else
return action_path;
}
/**
* glade_widget_action_class_new:
* @path: the action path
*
* Returns: a newlly created #GWActionClass for @path.
*/
GWActionClass *
glade_widget_action_class_new (const gchar *path)
{
GWActionClass *action;
action = g_slice_new0 (GWActionClass);
action->path = g_strdup (path);
action->id = gwa_action_path_get_id (action->path);
return action;
}
/**
......@@ -210,15 +310,11 @@ glade_widget_action_class_clone (GWActionClass * action)
g_return_val_if_fail (action != NULL, NULL);
copy = g_new0 (GWActionClass, 1);
copy->path = g_strdup (action->path);
copy = glade_widget_action_class_new (action->path);
copy->label = g_strdup (action->label);
copy->stock = g_strdup (action->stock);
copy->important = action->important;
/* id points to path! */
copy->id = copy->path + (action->id - action->path);
for (l = action->actions; l; l = g_list_next (l))
{
GWActionClass *child = glade_widget_action_class_clone (l->data);
......@@ -231,47 +327,45 @@ glade_widget_action_class_clone (GWActionClass * action)
}
/**
* glade_widget_action_remove:
* @action: a #GladeWidgetAction
* @child: a #GladeWidgetAction
*
* Remove an action.
* glade_widegt_action_class_free:
* @action: a GWActionClass
*
* Returns: whether or not @child was removed from @action.
* Frees a GWActionClass.
*/
gboolean
glade_widget_action_remove (GladeWidgetAction * action,
GladeWidgetAction * child)
void
glade_widget_action_class_free (GWActionClass *action)
{
GList *l;
if (action->actions)
g_list_foreach (action->actions, (GFunc) glade_widget_action_class_free,
NULL);
g_return_val_if_fail (GLADE_IS_WIDGET_ACTION (action), FALSE);
g_return_val_if_fail (GLADE_IS_WIDGET_ACTION (child), FALSE);
/* Dont free id since it points into path directly */
g_free (action->path);
g_free (action->label);
g_free (action->stock);
for (l = action->actions; l; l = g_list_next (l))
{
if (child == l->data)
{
action->actions = g_list_remove (action->actions, child);
return TRUE;
}
}
return FALSE;
g_slice_free (GWActionClass, action);
}
/**
* glade_widget_action_set_sensitive:
* @action: a #GladeWidgetAction
* @sensitive:
*
* Set whether or not this action is sensitive.
*
*/
void
glade_widget_action_set_sensitive (GladeWidgetAction * action,
gboolean sensitive)
glade_widget_action_class_set_label (GWActionClass *action,
const gchar *label)
{
g_return_if_fail (GLADE_IS_WIDGET_ACTION (action));
action->sensitive = sensitive;
g_object_notify (G_OBJECT (action), "sensitive");
g_free (action->label);
action->label = g_strdup (label);
}
void
glade_widget_action_class_set_stock (GWActionClass *action,
const gchar *stock)
{
g_free (action->stock);
action->stock = g_strdup (stock);
}
void
glade_widget_action_class_set_important (GWActionClass *action,
gboolean important)
{
action->important = important;
}
......@@ -33,49 +33,64 @@ G_BEGIN_DECLS
#define GLADE_IS_WIDGET_ACTION_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GLADE_TYPE_WIDGET_ACTION))
#define GLADE_WIDGET_ACTION_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GLADE_TYPE_WIDGET_ACTION, GladeWidgetActionClass))
typedef struct _GladeWidgetActionClass GladeWidgetActionClass;
typedef struct _GladeWidgetAction GladeWidgetAction;
typedef struct _GWActionClass GWActionClass;
typedef struct _GladeWidgetActionClass GladeWidgetActionClass;
typedef struct _GladeWidgetAction GladeWidgetAction;
typedef struct _GladeWidgetActionPrivate GladeWidgetActionPrivate;
typedef struct _GWActionClass GWActionClass;
struct _GWActionClass
{
gchar *id; /* The identifier of this action in the action tree */
gchar *path; /* Full action path */
gchar *label; /* A translated label to show in the UI for this action */
gchar *stock; /* If set, this stock item will be shown in the UI along side
* the label */
gboolean important; /* If this action is important */
GList *actions; /* Recursive list of child actions */
const gchar *id; /* The identifier of this action in the action tree */
gchar *path; /* Full action path */
gchar *label; /* A translated label to show in the UI for this action */
gchar *stock; /* If set, this stock item will be shown in the UI along side
* the label */
gboolean important; /* If this action is important */
GList *actions;/* Recursive list of child actions */
};
struct _GladeWidgetActionClass
struct _GladeWidgetAction
{
GObjectClass parent_class;
GObject parent_instance;
GladeWidgetActionPrivate *priv;
};
struct _GladeWidgetAction
struct _GladeWidgetActionClass
{
GObject parent_instance;
GWActionClass *klass; /* The action class */
gboolean sensitive; /* If this action is sensitive or not */
GList *actions; /* List of actions */
GObjectClass parent_class;
void (* glade_reserved1) (void);
void (* glade_reserved2) (void);
void (* glade_reserved3) (void);
void (* glade_reserved4) (void);
};
GType glade_widget_action_get_type (void) G_GNUC_CONST;
void glade_widget_action_class_free (GWActionClass *action);
void glade_widget_action_set_sensitive (GladeWidgetAction *action,
gboolean sensitive);
gboolean glade_widget_action_get_sensitive (GladeWidgetAction *action);
void glade_widget_action_set_visible (GladeWidgetAction *action,
gboolean visible);
gboolean glade_widget_action_get_visible (GladeWidgetAction *action);
GList *glade_widget_action_get_children (GladeWidgetAction *action);
GWActionClass *glade_widget_action_get_class (GladeWidgetAction *action);
GWActionClass *glade_widget_action_class_clone (GWActionClass *action);
gboolean glade_widget_action_remove (GladeWidgetAction *action,
GladeWidgetAction *child);
GWActionClass *glade_widget_action_class_new (const gchar *path);
GWActionClass *glade_widget_action_class_clone (GWActionClass *action);
void glade_widget_action_class_free (GWActionClass *action);
void glade_widget_action_class_set_label (GWActionClass *action,
const gchar *label);
void glade_widget_action_class_set_stock (GWActionClass *action,
const gchar *stock);
void glade_widget_action_class_set_important (GWActionClass *action,
gboolean important);
void glade_widget_action_set_sensitive (GladeWidgetAction *action,
gboolean sensitive);
G_END_DECLS
#endif /* _GLADE_WIDGET_ACTION_H_ */
......@@ -3426,10 +3426,11 @@ gwa_action_get_last_group (GList * actions, const gchar * action_path)
}
static gboolean
glade_widget_adaptor_action_add_real (GList ** list,
const gchar * action_path,
const gchar * label,
const gchar * stock, gboolean important)
glade_widget_adaptor_action_add_real (GList **list,
const gchar *action_path,
const gchar *label,
const gchar *stock,
gboolean important)
{
GWActionClass *action, *group;
const gchar *id;
......@@ -3439,43 +3440,22 @@ glade_widget_adaptor_action_add_real (GList ** list,
if ((group = gwa_action_get_last_group (*list, action_path)))
list = &group->actions;
if ((action = gwa_action_lookup (*list, id)))
{
/* Update parent's label/stock */
if (label && action->label)
{
g_free (action->label);
if (strcmp (label, "") == 0)
label = NULL;
action->label = (label) ? g_strdup (label) : NULL;
}
if (stock && action->stock)
{
g_free (action->stock);
if (strcmp (stock, "") == 0)
stock = NULL;
action->stock = (stock) ? g_strdup (stock) : NULL;
}
}
else
if (strcmp (label, "") == 0)
label = NULL;
if (stock && strcmp (stock, "") == 0)
stock = NULL;
if ((action = gwa_action_lookup (*list, id)) == NULL)
{
/* New Action */
action = g_new0 (GWActionClass, 1);
action->path = g_strdup (action_path);
action->id = (gchar *) gwa_action_path_get_id (action->path);
if (label && strcmp (label, "") == 0)
label = NULL;
if (stock && strcmp (stock, "") == 0)
stock = NULL;
action = glade_widget_action_class_new (action_path);
action->label = (label) ? g_strdup (label) : NULL;
action->stock = (stock) ? g_strdup (stock) : NULL;
*list = g_list_append (*list, action);
}
action->important = important;
*list = g_list_append (*list, action);
glade_widget_action_class_set_label (action, label);
glade_widget_action_class_set_stock (action, stock);
glade_widget_action_class_set_important (action, important);
return TRUE;
}
......
......@@ -4137,30 +4137,22 @@ glade_widget_placeholder_relation (GladeWidget * parent, GladeWidget * widget)
}
static GladeWidgetAction *
glade_widget_action_lookup (GList ** actions, const gchar * path,
gboolean remove)
glade_widget_action_lookup (GList *actions, const gchar * path)
{
GList *l;
for (l = *actions; l; l = g_list_next (l))
for (l = actions; l; l = g_list_next (l))
{
GladeWidgetAction *action = l->data;
GladeWidgetAction *action = l->data;
GWActionClass *aclass = glade_widget_action_get_class (action);
GList *children = glade_widget_action_get_children (action);
if (strcmp (action->klass->path, path) == 0)
{
if (remove)
{
*actions = g_list_remove (*actions, action);
g_object_unref (action);
return NULL;
}
return action;
}
if (strcmp (aclass->path, path) == 0)
return action;
if (action->actions &&
g_str_has_prefix (path, action->klass->path) &&
(action =
glade_widget_action_lookup (&action->actions, path, remove)))
if (children &&
g_str_has_prefix (path, aclass->path) &&
(action = glade_widget_action_lookup (children, path)))
return action;
}
......@@ -4182,7 +4174,7 @@ glade_widget_get_action (GladeWidget * widget, const gchar * action_path)
g_return_val_if_fail (GLADE_IS_WIDGET (widget), NULL);
g_return_val_if_fail (action_path != NULL, NULL);
return glade_widget_action_lookup (&widget->priv->actions, action_path, FALSE);
return glade_widget_action_lookup (widget->priv->actions, action_path);
}
/**
......@@ -4200,8 +4192,7 @@ glade_widget_get_pack_action (GladeWidget * widget, const gchar * action_path)
g_return_val_if_fail (GLADE_IS_WIDGET (widget), NULL);
g_return_val_if_fail (action_path != NULL, NULL);
return glade_widget_action_lookup (&widget->priv->packing_actions, action_path,
FALSE);
return glade_widget_action_lookup (widget->priv->packing_actions, action_path);
}
......@@ -4278,38 +4269,60 @@ glade_widget_set_pack_action_sensitive (GladeWidget * widget,
/**
* glade_widget_remove_action:
* glade_widget_set_action_visible:
* @widget: a #GladeWidget
* @action_path: a full action path including groups
* @visible: setting visible or invisible
*
* Remove an action.
* Sets the visibility of @action_path in @widget
*
* Returns: whether @action_path was found or not.
*/
void
glade_widget_remove_action (GladeWidget * widget, const gchar * action_path)
gboolean
glade_widget_set_action_visible (GladeWidget *widget,
const gchar *action_path,
gboolean visible)
{
g_return_if_fail (GLADE_IS_WIDGET (widget));
g_return_if_fail (action_path != NULL);
GladeWidgetAction *action;
g_return_val_if_fail (GLADE_IS_WIDGET (widget), FALSE);
glade_widget_action_lookup (&widget->priv->actions, action_path, TRUE);
if ((action = glade_widget_get_action (widget, action_path)) != NULL)
{
glade_widget_action_set_visible (action, visible);
return TRUE;
}
return FALSE;
}
/**
* glade_widget_remove_pack_action:
* glade_widget_set_pack_action_visible:
* @widget: a #GladeWidget
* @action_path: a full action path including groups
* @visible: setting visible or invisible
*
* Sets the visibility of @action_path in @widget
*
* Remove a packing action.
* Returns: whether @action_path was found or not.
*/
void
glade_widget_remove_pack_action (GladeWidget * widget,
const gchar * action_path)
gboolean
glade_widget_set_pack_action_visible (GladeWidget *widget,
const gchar *action_path,
gboolean visible)
{
g_return_if_fail (GLADE_IS_WIDGET (widget));
g_return_if_fail (action_path != NULL);
GladeWidgetAction *action;
glade_widget_action_lookup (&widget->priv->packing_actions, action_path, TRUE);
g_return_val_if_fail (GLADE_IS_WIDGET (widget), FALSE);
if ((action = glade_widget_get_pack_action (widget, action_path)) != NULL)
{
glade_widget_action_set_visible (action, visible);
return TRUE;
}
return FALSE;
}